LyoKICogIGxpbnV4L2RyaXZlcnMvbW1jL2hvc3Qvb21hcC5jCiAqCiAqICBDb3B5cmlnaHQgKEMpIDIwMDQgTm9raWEgQ29ycG9yYXRpb24KICogIFdyaXR0ZW4gYnkgVHV1a2thIFRpa2thbmVuIGFuZCBKdWhhIFlyavZs5DxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqICBNaXNjIGhhY2tzIGhlcmUgYW5kIHRoZXJlIGJ5IFRvbnkgTGluZGdyZW4gPHRvbnlAYXRvbWlkZS5jb20+CiAqICBPdGhlciBoYWNrcyAoRE1BLCBTRCwgZXRjKSBieSBEYXZpZCBCcm93bmVsbAogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGVwYXJhbS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zcGlubG9jay5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L21tYy9ob3N0Lmg+CiNpbmNsdWRlIDxsaW51eC9tbWMvY2FyZC5oPgojaW5jbHVkZSA8bGludXgvY2xrLmg+CiNpbmNsdWRlIDxsaW51eC9zY2F0dGVybGlzdC5oPgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2lycS5oPgojaW5jbHVkZSA8YXNtL21hY2gtdHlwZXMuaD4KCiNpbmNsdWRlIDxhc20vYXJjaC9ib2FyZC5oPgojaW5jbHVkZSA8YXNtL2FyY2gvZ3Bpby5oPgojaW5jbHVkZSA8YXNtL2FyY2gvZG1hLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9tdXguaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2ZwZ2EuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL3RwczY1MDEwLmg+CgojZGVmaW5lCU9NQVBfTU1DX1JFR19DTUQJMHgwMAojZGVmaW5lCU9NQVBfTU1DX1JFR19BUkdMCTB4MDQKI2RlZmluZQlPTUFQX01NQ19SRUdfQVJHSAkweDA4CiNkZWZpbmUJT01BUF9NTUNfUkVHX0NPTgkweDBjCiNkZWZpbmUJT01BUF9NTUNfUkVHX1NUQVQJMHgxMAojZGVmaW5lCU9NQVBfTU1DX1JFR19JRQkJMHgxNAojZGVmaW5lCU9NQVBfTU1DX1JFR19DVE8JMHgxOAojZGVmaW5lCU9NQVBfTU1DX1JFR19EVE8JMHgxYwojZGVmaW5lCU9NQVBfTU1DX1JFR19EQVRBCTB4MjAKI2RlZmluZQlPTUFQX01NQ19SRUdfQkxFTgkweDI0CiNkZWZpbmUJT01BUF9NTUNfUkVHX05CTEsJMHgyOAojZGVmaW5lCU9NQVBfTU1DX1JFR19CVUYJMHgyYwojZGVmaW5lIE9NQVBfTU1DX1JFR19TRElPCTB4MzQKI2RlZmluZQlPTUFQX01NQ19SRUdfUkVWCTB4M2MKI2RlZmluZQlPTUFQX01NQ19SRUdfUlNQMAkweDQwCiNkZWZpbmUJT01BUF9NTUNfUkVHX1JTUDEJMHg0NAojZGVmaW5lCU9NQVBfTU1DX1JFR19SU1AyCTB4NDgKI2RlZmluZQlPTUFQX01NQ19SRUdfUlNQMwkweDRjCiNkZWZpbmUJT01BUF9NTUNfUkVHX1JTUDQJMHg1MAojZGVmaW5lCU9NQVBfTU1DX1JFR19SU1A1CTB4NTQKI2RlZmluZQlPTUFQX01NQ19SRUdfUlNQNgkweDU4CiNkZWZpbmUJT01BUF9NTUNfUkVHX1JTUDcJMHg1YwojZGVmaW5lCU9NQVBfTU1DX1JFR19JT1NSCTB4NjAKI2RlZmluZQlPTUFQX01NQ19SRUdfU1lTQwkweDY0CiNkZWZpbmUJT01BUF9NTUNfUkVHX1NZU1MJMHg2OAoKI2RlZmluZQlPTUFQX01NQ19TVEFUX0NBUkRfRVJSCQkoMSA8PCAxNCkKI2RlZmluZQlPTUFQX01NQ19TVEFUX0NBUkRfSVJRCQkoMSA8PCAxMykKI2RlZmluZQlPTUFQX01NQ19TVEFUX09DUl9CVVNZCQkoMSA8PCAxMikKI2RlZmluZQlPTUFQX01NQ19TVEFUX0FfRU1QVFkJCSgxIDw8IDExKQojZGVmaW5lCU9NQVBfTU1DX1NUQVRfQV9GVUxMCQkoMSA8PCAxMCkKI2RlZmluZQlPTUFQX01NQ19TVEFUX0NNRF9DUkMJCSgxIDw8ICA4KQojZGVmaW5lCU9NQVBfTU1DX1NUQVRfQ01EX1RPVVQJCSgxIDw8ICA3KQojZGVmaW5lCU9NQVBfTU1DX1NUQVRfREFUQV9DUkMJCSgxIDw8ICA2KQojZGVmaW5lCU9NQVBfTU1DX1NUQVRfREFUQV9UT1VUCQkoMSA8PCAgNSkKI2RlZmluZQlPTUFQX01NQ19TVEFUX0VORF9CVVNZCQkoMSA8PCAgNCkKI2RlZmluZQlPTUFQX01NQ19TVEFUX0VORF9PRl9EQVRBCSgxIDw8ICAzKQojZGVmaW5lCU9NQVBfTU1DX1NUQVRfQ0FSRF9CVVNZCQkoMSA8PCAgMikKI2RlZmluZQlPTUFQX01NQ19TVEFUX0VORF9PRl9DTUQJKDEgPDwgIDApCgojZGVmaW5lIE9NQVBfTU1DX1JFQUQoaG9zdCwgcmVnKQlfX3Jhd19yZWFkdygoaG9zdCktPnZpcnRfYmFzZSArIE9NQVBfTU1DX1JFR18jI3JlZykKI2RlZmluZSBPTUFQX01NQ19XUklURShob3N0LCByZWcsIHZhbCkJX19yYXdfd3JpdGV3KCh2YWwpLCAoaG9zdCktPnZpcnRfYmFzZSArIE9NQVBfTU1DX1JFR18jI3JlZykKCi8qCiAqIENvbW1hbmQgdHlwZXMKICovCiNkZWZpbmUgT01BUF9NTUNfQ01EVFlQRV9CQwkwCiNkZWZpbmUgT01BUF9NTUNfQ01EVFlQRV9CQ1IJMQojZGVmaW5lIE9NQVBfTU1DX0NNRFRZUEVfQUMJMgojZGVmaW5lIE9NQVBfTU1DX0NNRFRZUEVfQURUQwkzCgoKI2RlZmluZSBEUklWRVJfTkFNRSAibW1jaS1vbWFwIgoKLyogU3BlY2lmaWVzIGhvdyBvZnRlbiBpbiBtaWxsaXNlY3MgdG8gcG9sbCBmb3IgY2FyZCBzdGF0dXMgY2hhbmdlcwogKiB3aGVuIHRoZSBjb3ZlciBzd2l0Y2ggaXMgb3BlbiAqLwojZGVmaW5lIE9NQVBfTU1DX1NXSVRDSF9QT0xMX0RFTEFZCTUwMAoKc3RhdGljIGludCBtbWNfb21hcF9lbmFibGVfcG9sbCA9IDE7CgpzdHJ1Y3QgbW1jX29tYXBfaG9zdCB7CglpbnQJCQlpbml0aWFsaXplZDsKCWludAkJCXN1c3BlbmRlZDsKCXN0cnVjdCBtbWNfcmVxdWVzdCAqCW1ycTsKCXN0cnVjdCBtbWNfY29tbWFuZCAqCWNtZDsKCXN0cnVjdCBtbWNfZGF0YSAqCWRhdGE7CglzdHJ1Y3QgbW1jX2hvc3QgKgltbWM7CglzdHJ1Y3QgZGV2aWNlICoJCWRldjsKCXVuc2lnbmVkIGNoYXIJCWlkOyAvKiAxNnh4IGNoaXBzIGhhdmUgMiBNTUMgYmxvY2tzICovCglzdHJ1Y3QgY2xrICoJCWljbGs7CglzdHJ1Y3QgY2xrICoJCWZjbGs7CglzdHJ1Y3QgcmVzb3VyY2UJCSptZW1fcmVzOwoJdm9pZCBfX2lvbWVtCQkqdmlydF9iYXNlOwoJdW5zaWduZWQgaW50CQlwaHlzX2Jhc2U7CglpbnQJCQlpcnE7Cgl1bnNpZ25lZCBjaGFyCQlidXNfbW9kZTsKCXVuc2lnbmVkIGNoYXIJCWh3X2J1c19tb2RlOwoKCXVuc2lnbmVkIGludAkJc2dfbGVuOwoJaW50CQkJc2dfaWR4OwoJdTE2ICoJCQlidWZmZXI7Cgl1MzIJCQlidWZmZXJfYnl0ZXNfbGVmdDsKCXUzMgkJCXRvdGFsX2J5dGVzX2xlZnQ7CgoJdW5zaWduZWQJCXVzZV9kbWE6MTsKCXVuc2lnbmVkCQlicnNfcmVjZWl2ZWQ6MSwgZG1hX2RvbmU6MTsKCXVuc2lnbmVkCQlkbWFfaXNfcmVhZDoxOwoJdW5zaWduZWQJCWRtYV9pbl91c2U6MTsKCWludAkJCWRtYV9jaDsKCXNwaW5sb2NrX3QJCWRtYV9sb2NrOwoJc3RydWN0IHRpbWVyX2xpc3QJZG1hX3RpbWVyOwoJdW5zaWduZWQJCWRtYV9sZW47CgoJc2hvcnQJCQlwb3dlcl9waW47CglzaG9ydAkJCXdwX3BpbjsKCglpbnQJCQlzd2l0Y2hfcGluOwoJc3RydWN0IHdvcmtfc3RydWN0CXN3aXRjaF93b3JrOwoJc3RydWN0IHRpbWVyX2xpc3QJc3dpdGNoX3RpbWVyOwoJaW50CQkJc3dpdGNoX2xhc3Rfc3RhdGU7Cn07CgpzdGF0aWMgaW5saW5lIGludAptbWNfb21hcF9jb3Zlcl9pc19vcGVuKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0KQp7CglpZiAoaG9zdC0+c3dpdGNoX3BpbiA8IDApCgkJcmV0dXJuIDA7CglyZXR1cm4gb21hcF9nZXRfZ3Bpb19kYXRhaW4oaG9zdC0+c3dpdGNoX3Bpbik7Cn0KCnN0YXRpYyBzc2l6ZV90Cm1tY19vbWFwX3Nob3dfY292ZXJfc3dpdGNoKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gZGV2X2dldF9kcnZkYXRhKGRldik7CgoJcmV0dXJuIHNwcmludGYoYnVmLCAiJXNcbiIsIG1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCkgPyAib3BlbiIgOgoJCQkiY2xvc2VkIik7Cn0KCnN0YXRpYyBERVZJQ0VfQVRUUihjb3Zlcl9zd2l0Y2gsIFNfSVJVR08sIG1tY19vbWFwX3Nob3dfY292ZXJfc3dpdGNoLCBOVUxMKTsKCnN0YXRpYyBzc2l6ZV90Cm1tY19vbWFwX3Nob3dfZW5hYmxlX3BvbGwoc3RydWN0IGRldmljZSAqZGV2LAoJc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNucHJpbnRmKGJ1ZiwgUEFHRV9TSVpFLCAiJWRcbiIsIG1tY19vbWFwX2VuYWJsZV9wb2xsKTsKfQoKc3RhdGljIHNzaXplX3QKbW1jX29tYXBfc3RvcmVfZW5hYmxlX3BvbGwoc3RydWN0IGRldmljZSAqZGV2LAoJc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNvbnN0IGNoYXIgKmJ1ZiwKCXNpemVfdCBzaXplKQp7CglpbnQgZW5hYmxlX3BvbGw7CgoJaWYgKHNzY2FuZihidWYsICIlMTBkIiwgJmVuYWJsZV9wb2xsKSAhPSAxKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChlbmFibGVfcG9sbCAhPSBtbWNfb21hcF9lbmFibGVfcG9sbCkgewoJCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gZGV2X2dldF9kcnZkYXRhKGRldik7CgoJCW1tY19vbWFwX2VuYWJsZV9wb2xsID0gZW5hYmxlX3BvbGw7CgkJaWYgKGVuYWJsZV9wb2xsICYmIGhvc3QtPnN3aXRjaF9waW4gPj0gMCkKCQkJc2NoZWR1bGVfd29yaygmaG9zdC0+c3dpdGNoX3dvcmspOwoJfQoJcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBERVZJQ0VfQVRUUihlbmFibGVfcG9sbCwgMDY2NCwKCQkgICBtbWNfb21hcF9zaG93X2VuYWJsZV9wb2xsLCBtbWNfb21hcF9zdG9yZV9lbmFibGVfcG9sbCk7CgpzdGF0aWMgdm9pZAptbWNfb21hcF9zdGFydF9jb21tYW5kKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2NvbW1hbmQgKmNtZCkKewoJdTMyIGNtZHJlZzsKCXUzMiByZXNwdHlwZTsKCXUzMiBjbWR0eXBlOwoKCWhvc3QtPmNtZCA9IGNtZDsKCglyZXNwdHlwZSA9IDA7CgljbWR0eXBlID0gMDsKCgkvKiBPdXIgaGFyZHdhcmUgbmVlZHMgdG8ga25vdyBleGFjdCB0eXBlICovCglzd2l0Y2ggKG1tY19yZXNwX3R5cGUoY21kKSkgewoJY2FzZSBNTUNfUlNQX05PTkU6CgkJYnJlYWs7CgljYXNlIE1NQ19SU1BfUjE6CgljYXNlIE1NQ19SU1BfUjFCOgoJCS8qIHJlc3AgMSwgMWIsIDYsIDcgKi8KCQlyZXNwdHlwZSA9IDE7CgkJYnJlYWs7CgljYXNlIE1NQ19SU1BfUjI6CgkJcmVzcHR5cGUgPSAyOwoJCWJyZWFrOwoJY2FzZSBNTUNfUlNQX1IzOgoJCXJlc3B0eXBlID0gMzsKCQlicmVhazsKCWRlZmF1bHQ6CgkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksICJJbnZhbGlkIHJlc3BvbnNlIHR5cGU6ICUwNHhcbiIsIG1tY19yZXNwX3R5cGUoY21kKSk7CgkJYnJlYWs7Cgl9CgoJaWYgKG1tY19jbWRfdHlwZShjbWQpID09IE1NQ19DTURfQURUQykgewoJCWNtZHR5cGUgPSBPTUFQX01NQ19DTURUWVBFX0FEVEM7Cgl9IGVsc2UgaWYgKG1tY19jbWRfdHlwZShjbWQpID09IE1NQ19DTURfQkMpIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9CQzsKCX0gZWxzZSBpZiAobW1jX2NtZF90eXBlKGNtZCkgPT0gTU1DX0NNRF9CQ1IpIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9CQ1I7Cgl9IGVsc2UgewoJCWNtZHR5cGUgPSBPTUFQX01NQ19DTURUWVBFX0FDOwoJfQoKCWNtZHJlZyA9IGNtZC0+b3Bjb2RlIHwgKHJlc3B0eXBlIDw8IDgpIHwgKGNtZHR5cGUgPDwgMTIpOwoKCWlmIChob3N0LT5idXNfbW9kZSA9PSBNTUNfQlVTTU9ERV9PUEVORFJBSU4pCgkJY21kcmVnIHw9IDEgPDwgNjsKCglpZiAoY21kLT5mbGFncyAmIE1NQ19SU1BfQlVTWSkKCQljbWRyZWcgfD0gMSA8PCAxMTsKCglpZiAoaG9zdC0+ZGF0YSAmJiAhKGhvc3QtPmRhdGEtPmZsYWdzICYgTU1DX0RBVEFfV1JJVEUpKQoJCWNtZHJlZyB8PSAxIDw8IDE1OwoKCWNsa19lbmFibGUoaG9zdC0+ZmNsayk7CgoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQ1RPLCAyMDApOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQVJHTCwgY21kLT5hcmcgJiAweGZmZmYpOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQVJHSCwgY21kLT5hcmcgPj4gMTYpOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgSUUsCgkJICAgICAgIE9NQVBfTU1DX1NUQVRfQV9FTVBUWSAgICB8IE9NQVBfTU1DX1NUQVRfQV9GVUxMICAgIHwKCQkgICAgICAgT01BUF9NTUNfU1RBVF9DTURfQ1JDICAgIHwgT01BUF9NTUNfU1RBVF9DTURfVE9VVCAgfAoJCSAgICAgICBPTUFQX01NQ19TVEFUX0RBVEFfQ1JDICAgfCBPTUFQX01NQ19TVEFUX0RBVEFfVE9VVCB8CgkJICAgICAgIE9NQVBfTU1DX1NUQVRfRU5EX09GX0NNRCB8IE9NQVBfTU1DX1NUQVRfQ0FSRF9FUlIgIHwKCQkgICAgICAgT01BUF9NTUNfU1RBVF9FTkRfT0ZfREFUQSk7CglPTUFQX01NQ19XUklURShob3N0LCBDTUQsIGNtZHJlZyk7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX3hmZXJfZG9uZShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7CglpZiAoaG9zdC0+ZG1hX2luX3VzZSkgewoJCWVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRtYV9kYXRhX2RpcjsKCgkJQlVHX09OKGhvc3QtPmRtYV9jaCA8IDApOwoJCWlmIChkYXRhLT5lcnJvcikKCQkJb21hcF9zdG9wX2RtYShob3N0LT5kbWFfY2gpOwoJCS8qIFJlbGVhc2UgRE1BIGNoYW5uZWwgbGF6aWx5ICovCgkJbW9kX3RpbWVyKCZob3N0LT5kbWFfdGltZXIsIGppZmZpZXMgKyBIWik7CgkJaWYgKGRhdGEtPmZsYWdzICYgTU1DX0RBVEFfV1JJVEUpCgkJCWRtYV9kYXRhX2RpciA9IERNQV9UT19ERVZJQ0U7CgkJZWxzZQoJCQlkbWFfZGF0YV9kaXIgPSBETUFfRlJPTV9ERVZJQ0U7CgkJZG1hX3VubWFwX3NnKG1tY19kZXYoaG9zdC0+bW1jKSwgZGF0YS0+c2csIGhvc3QtPnNnX2xlbiwKCQkJICAgICBkbWFfZGF0YV9kaXIpOwoJfQoJaG9zdC0+ZGF0YSA9IE5VTEw7Cglob3N0LT5zZ19sZW4gPSAwOwoJY2xrX2Rpc2FibGUoaG9zdC0+ZmNsayk7CgoJLyogTk9URTogIE1NQyBsYXllciB3aWxsIHNvbWV0aW1lcyBwb2xsLXdhaXQgQ01EMTMgbmV4dCwgaXNzdWluZwoJICogZG96ZW5zIG9mIHJlcXVlc3RzIHVudGlsIHRoZSBjYXJkIGZpbmlzaGVzIHdyaXRpbmcgZGF0YS4KCSAqIEl0J2QgYmUgY2hlYXBlciB0byBqdXN0IHdhaXQgdGlsbCBhbiBFT0ZCIGludGVycnVwdCBhcnJpdmVzLi4uCgkgKi8KCglpZiAoIWRhdGEtPnN0b3ApIHsKCQlob3N0LT5tcnEgPSBOVUxMOwoJCW1tY19yZXF1ZXN0X2RvbmUoaG9zdC0+bW1jLCBkYXRhLT5tcnEpOwoJCXJldHVybjsKCX0KCgltbWNfb21hcF9zdGFydF9jb21tYW5kKGhvc3QsIGRhdGEtPnN0b3ApOwp9CgpzdGF0aWMgdm9pZAptbWNfb21hcF9lbmRfb2ZfZGF0YShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGRvbmU7CgoJaWYgKCFob3N0LT5kbWFfaW5fdXNlKSB7CgkJbW1jX29tYXBfeGZlcl9kb25lKGhvc3QsIGRhdGEpOwoJCXJldHVybjsKCX0KCWRvbmUgPSAwOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmhvc3QtPmRtYV9sb2NrLCBmbGFncyk7CglpZiAoaG9zdC0+ZG1hX2RvbmUpCgkJZG9uZSA9IDE7CgllbHNlCgkJaG9zdC0+YnJzX3JlY2VpdmVkID0gMTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmhvc3QtPmRtYV9sb2NrLCBmbGFncyk7CglpZiAoZG9uZSkKCQltbWNfb21hcF94ZmVyX2RvbmUoaG9zdCwgZGF0YSk7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX2RtYV90aW1lcih1bnNpZ25lZCBsb25nIGRhdGEpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gKHN0cnVjdCBtbWNfb21hcF9ob3N0ICopIGRhdGE7CgoJQlVHX09OKGhvc3QtPmRtYV9jaCA8IDApOwoJb21hcF9mcmVlX2RtYShob3N0LT5kbWFfY2gpOwoJaG9zdC0+ZG1hX2NoID0gLTE7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX2RtYV9kb25lKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2RhdGEgKmRhdGEpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZG9uZTsKCglkb25lID0gMDsKCXNwaW5fbG9ja19pcnFzYXZlKCZob3N0LT5kbWFfbG9jaywgZmxhZ3MpOwoJaWYgKGhvc3QtPmJyc19yZWNlaXZlZCkKCQlkb25lID0gMTsKCWVsc2UKCQlob3N0LT5kbWFfZG9uZSA9IDE7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZob3N0LT5kbWFfbG9jaywgZmxhZ3MpOwoJaWYgKGRvbmUpCgkJbW1jX29tYXBfeGZlcl9kb25lKGhvc3QsIGRhdGEpOwp9CgpzdGF0aWMgdm9pZAptbWNfb21hcF9jbWRfZG9uZShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19jb21tYW5kICpjbWQpCnsKCWhvc3QtPmNtZCA9IE5VTEw7CgoJaWYgKGNtZC0+ZmxhZ3MgJiBNTUNfUlNQX1BSRVNFTlQpIHsKCQlpZiAoY21kLT5mbGFncyAmIE1NQ19SU1BfMTM2KSB7CgkJCS8qIHJlc3BvbnNlIHR5cGUgMiAqLwoJCQljbWQtPnJlc3BbM10gPQoJCQkJT01BUF9NTUNfUkVBRChob3N0LCBSU1AwKSB8CgkJCQkoT01BUF9NTUNfUkVBRChob3N0LCBSU1AxKSA8PCAxNik7CgkJCWNtZC0+cmVzcFsyXSA9CgkJCQlPTUFQX01NQ19SRUFEKGhvc3QsIFJTUDIpIHwKCQkJCShPTUFQX01NQ19SRUFEKGhvc3QsIFJTUDMpIDw8IDE2KTsKCQkJY21kLT5yZXNwWzFdID0KCQkJCU9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQNCkgfAoJCQkJKE9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQNSkgPDwgMTYpOwoJCQljbWQtPnJlc3BbMF0gPQoJCQkJT01BUF9NTUNfUkVBRChob3N0LCBSU1A2KSB8CgkJCQkoT01BUF9NTUNfUkVBRChob3N0LCBSU1A3KSA8PCAxNik7CgkJfSBlbHNlIHsKCQkJLyogcmVzcG9uc2UgdHlwZXMgMSwgMWIsIDMsIDQsIDUsIDYgKi8KCQkJY21kLT5yZXNwWzBdID0KCQkJCU9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQNikgfAoJCQkJKE9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQNykgPDwgMTYpOwoJCX0KCX0KCglpZiAoaG9zdC0+ZGF0YSA9PSBOVUxMIHx8IGNtZC0+ZXJyb3IpIHsKCQlob3N0LT5tcnEgPSBOVUxMOwoJCWNsa19kaXNhYmxlKGhvc3QtPmZjbGspOwoJCW1tY19yZXF1ZXN0X2RvbmUoaG9zdC0+bW1jLCBjbWQtPm1ycSk7Cgl9Cn0KCi8qIFBJTyBvbmx5ICovCnN0YXRpYyB2b2lkCm1tY19vbWFwX3NnX3RvX2J1ZihzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCkKewoJc3RydWN0IHNjYXR0ZXJsaXN0ICpzZzsKCglzZyA9IGhvc3QtPmRhdGEtPnNnICsgaG9zdC0+c2dfaWR4OwoJaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgPSBzZy0+bGVuZ3RoOwoJaG9zdC0+YnVmZmVyID0gc2dfdmlydChzZyk7CglpZiAoaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgPiBob3N0LT50b3RhbF9ieXRlc19sZWZ0KQoJCWhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0ID0gaG9zdC0+dG90YWxfYnl0ZXNfbGVmdDsKfQoKLyogUElPIG9ubHkgKi8Kc3RhdGljIHZvaWQKbW1jX29tYXBfeGZlcl9kYXRhKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBpbnQgd3JpdGUpCnsKCWludCBuOwoKCWlmIChob3N0LT5idWZmZXJfYnl0ZXNfbGVmdCA9PSAwKSB7CgkJaG9zdC0+c2dfaWR4Kys7CgkJQlVHX09OKGhvc3QtPnNnX2lkeCA9PSBob3N0LT5zZ19sZW4pOwoJCW1tY19vbWFwX3NnX3RvX2J1Zihob3N0KTsKCX0KCW4gPSA2NDsKCWlmIChuID4gaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQpCgkJbiA9IGhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0OwoJaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgLT0gbjsKCWhvc3QtPnRvdGFsX2J5dGVzX2xlZnQgLT0gbjsKCWhvc3QtPmRhdGEtPmJ5dGVzX3hmZXJlZCArPSBuOwoKCWlmICh3cml0ZSkgewoJCV9fcmF3X3dyaXRlc3coaG9zdC0+dmlydF9iYXNlICsgT01BUF9NTUNfUkVHX0RBVEEsIGhvc3QtPmJ1ZmZlciwgbik7Cgl9IGVsc2UgewoJCV9fcmF3X3JlYWRzdyhob3N0LT52aXJ0X2Jhc2UgKyBPTUFQX01NQ19SRUdfREFUQSwgaG9zdC0+YnVmZmVyLCBuKTsKCX0KfQoKc3RhdGljIGlubGluZSB2b2lkIG1tY19vbWFwX3JlcG9ydF9pcnEodTE2IHN0YXR1cykKewoJc3RhdGljIGNvbnN0IGNoYXIgKm1tY19vbWFwX3N0YXR1c19iaXRzW10gPSB7CgkJIkVPQyIsICJDRCIsICJDQiIsICJCUlMiLCAiRU9GQiIsICJEVE8iLCAiRENSQyIsICJDVE8iLAoJCSJDQ1JDIiwgIkNSVyIsICJBRiIsICJBRSIsICJPQ1JCIiwgIkNJUlEiLCAiQ0VSUiIKCX07CglpbnQgaSwgYyA9IDA7CgoJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUobW1jX29tYXBfc3RhdHVzX2JpdHMpOyBpKyspCgkJaWYgKHN0YXR1cyAmICgxIDw8IGkpKSB7CgkJCWlmIChjKQoJCQkJcHJpbnRrKCIgIik7CgkJCXByaW50aygiJXMiLCBtbWNfb21hcF9zdGF0dXNfYml0c1tpXSk7CgkJCWMrKzsKCQl9Cn0KCnN0YXRpYyBpcnFyZXR1cm5fdCBtbWNfb21hcF9pcnEoaW50IGlycSwgdm9pZCAqZGV2X2lkKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqIGhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKilkZXZfaWQ7Cgl1MTYgc3RhdHVzOwoJaW50IGVuZF9jb21tYW5kOwoJaW50IGVuZF90cmFuc2ZlcjsKCWludCB0cmFuc2Zlcl9lcnJvcjsKCglpZiAoaG9zdC0+Y21kID09IE5VTEwgJiYgaG9zdC0+ZGF0YSA9PSBOVUxMKSB7CgkJc3RhdHVzID0gT01BUF9NTUNfUkVBRChob3N0LCBTVEFUKTsKCQlkZXZfaW5mbyhtbWNfZGV2KGhvc3QtPm1tYyksInNwdXJpb3VzIGlycSAweCUwNHhcbiIsIHN0YXR1cyk7CgkJaWYgKHN0YXR1cyAhPSAwKSB7CgkJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIFNUQVQsIHN0YXR1cyk7CgkJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIElFLCAwKTsKCQl9CgkJcmV0dXJuIElSUV9IQU5ETEVEOwoJfQoKCWVuZF9jb21tYW5kID0gMDsKCWVuZF90cmFuc2ZlciA9IDA7Cgl0cmFuc2Zlcl9lcnJvciA9IDA7CgoJd2hpbGUgKChzdGF0dXMgPSBPTUFQX01NQ19SRUFEKGhvc3QsIFNUQVQpKSAhPSAwKSB7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgU1RBVCwgc3RhdHVzKTsKI2lmZGVmIENPTkZJR19NTUNfREVCVUcKCQlkZXZfZGJnKG1tY19kZXYoaG9zdC0+bW1jKSwgIk1NQyBJUlEgJTA0eCAoQ01EICVkKTogIiwKCQkJc3RhdHVzLCBob3N0LT5jbWQgIT0gTlVMTCA/IGhvc3QtPmNtZC0+b3Bjb2RlIDogLTEpOwoJCW1tY19vbWFwX3JlcG9ydF9pcnEoc3RhdHVzKTsKCQlwcmludGsoIlxuIik7CiNlbmRpZgoJCWlmIChob3N0LT50b3RhbF9ieXRlc19sZWZ0KSB7CgkJCWlmICgoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9BX0ZVTEwpIHx8CgkJCSAgICAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9FTkRfT0ZfREFUQSkpCgkJCQltbWNfb21hcF94ZmVyX2RhdGEoaG9zdCwgMCk7CgkJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0FfRU1QVFkpCgkJCQltbWNfb21hcF94ZmVyX2RhdGEoaG9zdCwgMSk7CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9FTkRfT0ZfREFUQSkgewoJCQllbmRfdHJhbnNmZXIgPSAxOwoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfREFUQV9UT1VUKSB7CgkJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAiZGF0YSB0aW1lb3V0XG4iKTsKCQkJaWYgKGhvc3QtPmRhdGEpIHsKCQkJCWhvc3QtPmRhdGEtPmVycm9yID0gLUVUSU1FRE9VVDsKCQkJCXRyYW5zZmVyX2Vycm9yID0gMTsKCQkJfQoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfREFUQV9DUkMpIHsKCQkJaWYgKGhvc3QtPmRhdGEpIHsKCQkJCWhvc3QtPmRhdGEtPmVycm9yID0gLUVJTFNFUTsKCQkJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJCSAiZGF0YSBDUkMgZXJyb3IsIGJ5dGVzIGxlZnQgJWRcbiIsCgkJCQkJaG9zdC0+dG90YWxfYnl0ZXNfbGVmdCk7CgkJCQl0cmFuc2Zlcl9lcnJvciA9IDE7CgkJCX0gZWxzZSB7CgkJCQlkZXZfZGJnKG1tY19kZXYoaG9zdC0+bW1jKSwgImRhdGEgQ1JDIGVycm9yXG4iKTsKCQkJfQoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfQ01EX1RPVVQpIHsKCQkJLyogVGltZW91dHMgYXJlIHJvdXRpbmUgd2l0aCBzb21lIGNvbW1hbmRzICovCgkJCWlmIChob3N0LT5jbWQpIHsKCQkJCWlmIChob3N0LT5jbWQtPm9wY29kZSAhPSBNTUNfQUxMX1NFTkRfQ0lEICYmCgkJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlICE9CgkJCQkJCU1NQ19TRU5EX09QX0NPTkQgJiYKCQkJCQkJaG9zdC0+Y21kLT5vcGNvZGUgIT0KCQkJCQkJTU1DX0FQUF9DTUQgJiYKCQkJCQkJIW1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCkpCgkJCQkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkJCSJjb21tYW5kIHRpbWVvdXQsIENNRCAlZFxuIiwKCQkJCQkJaG9zdC0+Y21kLT5vcGNvZGUpOwoJCQkJaG9zdC0+Y21kLT5lcnJvciA9IC1FVElNRURPVVQ7CgkJCQllbmRfY29tbWFuZCA9IDE7CgkJCX0KCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0NNRF9DUkMpIHsKCQkJaWYgKGhvc3QtPmNtZCkgewoJCQkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkJImNvbW1hbmQgQ1JDIGVycm9yIChDTUQlZCwgYXJnIDB4JTA4eClcbiIsCgkJCQkJaG9zdC0+Y21kLT5vcGNvZGUsIGhvc3QtPmNtZC0+YXJnKTsKCQkJCWhvc3QtPmNtZC0+ZXJyb3IgPSAtRUlMU0VROwoJCQkJZW5kX2NvbW1hbmQgPSAxOwoJCQl9IGVsc2UKCQkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJCSJjb21tYW5kIENSQyBlcnJvciB3aXRob3V0IGNtZD9cbiIpOwoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfQ0FSRF9FUlIpIHsKCQkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkiaWdub3JpbmcgY2FyZCBzdGF0dXMgZXJyb3IgKENNRCVkKVxuIiwKCQkJCWhvc3QtPmNtZC0+b3Bjb2RlKTsKCQkJZW5kX2NvbW1hbmQgPSAxOwoJCX0KCgkJLyoKCQkgKiBOT1RFOiBPbiAxNjEwIHRoZSBFTkRfT0ZfQ01EIG1heSBjb21lIHRvbyBlYXJseSB3aGVuCgkJICogc3RhcnRpbmcgYSB3cml0ZSAKCQkgKi8KCQlpZiAoKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfRU5EX09GX0NNRCkgJiYKCQkgICAgKCEoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9BX0VNUFRZKSkpIHsKCQkJZW5kX2NvbW1hbmQgPSAxOwoJCX0KCX0KCglpZiAoZW5kX2NvbW1hbmQpIHsKCQltbWNfb21hcF9jbWRfZG9uZShob3N0LCBob3N0LT5jbWQpOwoJfQoJaWYgKHRyYW5zZmVyX2Vycm9yKQoJCW1tY19vbWFwX3hmZXJfZG9uZShob3N0LCBob3N0LT5kYXRhKTsKCWVsc2UgaWYgKGVuZF90cmFuc2ZlcikKCQltbWNfb21hcF9lbmRfb2ZfZGF0YShob3N0LCBob3N0LT5kYXRhKTsKCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCnN0YXRpYyBpcnFyZXR1cm5fdCBtbWNfb21hcF9zd2l0Y2hfaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgZGV2X2lkOwoKCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCnN0YXRpYyB2b2lkIG1tY19vbWFwX3N3aXRjaF90aW1lcih1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgYXJnOwoKCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKfQoKc3RhdGljIHZvaWQgbW1jX29tYXBfc3dpdGNoX2hhbmRsZXIoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QgbW1jX29tYXBfaG9zdCwgc3dpdGNoX3dvcmspOwoJc3RydWN0IG1tY19jYXJkICpjYXJkOwoJc3RhdGljIGludCBjb21wbGFpbmVkID0gMDsKCWludCBjYXJkcyA9IDAsIGNvdmVyX29wZW47CgoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPT0gLTEpCgkJcmV0dXJuOwoJY292ZXJfb3BlbiA9IG1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCk7CglpZiAoY292ZXJfb3BlbiAhPSBob3N0LT5zd2l0Y2hfbGFzdF9zdGF0ZSkgewoJCWtvYmplY3RfdWV2ZW50KCZob3N0LT5kZXYtPmtvYmosIEtPQkpfQ0hBTkdFKTsKCQlob3N0LT5zd2l0Y2hfbGFzdF9zdGF0ZSA9IGNvdmVyX29wZW47Cgl9CgltbWNfZGV0ZWN0X2NoYW5nZShob3N0LT5tbWMsIDApOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjYXJkLCAmaG9zdC0+bW1jLT5jYXJkcywgbm9kZSkgewoJCWlmIChtbWNfY2FyZF9wcmVzZW50KGNhcmQpKQoJCQljYXJkcysrOwoJfQoJaWYgKG1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCkpIHsKCQlpZiAoIWNvbXBsYWluZWQpIHsKCQkJZGV2X2luZm8obW1jX2Rldihob3N0LT5tbWMpLCAiY292ZXIgaXMgb3BlblxuIik7CgkJCWNvbXBsYWluZWQgPSAxOwoJCX0KCQlpZiAobW1jX29tYXBfZW5hYmxlX3BvbGwpCgkJCW1vZF90aW1lcigmaG9zdC0+c3dpdGNoX3RpbWVyLCBqaWZmaWVzICsKCQkJCW1zZWNzX3RvX2ppZmZpZXMoT01BUF9NTUNfU1dJVENIX1BPTExfREVMQVkpKTsKCX0gZWxzZSB7CgkJY29tcGxhaW5lZCA9IDA7Cgl9Cn0KCi8qIFByZXBhcmUgdG8gdHJhbnNmZXIgdGhlIG5leHQgc2VnbWVudCBvZiBhIHNjYXR0ZXJsaXN0ICovCnN0YXRpYyB2b2lkCm1tY19vbWFwX3ByZXBhcmVfZG1hKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2RhdGEgKmRhdGEpCnsKCWludCBkbWFfY2ggPSBob3N0LT5kbWFfY2g7Cgl1bnNpZ25lZCBsb25nIGRhdGFfYWRkcjsKCXUxNiBidWYsIGZyYW1lOwoJdTMyIGNvdW50OwoJc3RydWN0IHNjYXR0ZXJsaXN0ICpzZyA9ICZkYXRhLT5zZ1tob3N0LT5zZ19pZHhdOwoJaW50IHNyY19wb3J0ID0gMDsKCWludCBkc3RfcG9ydCA9IDA7CglpbnQgc3luY19kZXYgPSAwOwoKCWRhdGFfYWRkciA9IGhvc3QtPnBoeXNfYmFzZSArIE9NQVBfTU1DX1JFR19EQVRBOwoJZnJhbWUgPSBkYXRhLT5ibGtzejsKCWNvdW50ID0gc2dfZG1hX2xlbihzZyk7CgoJaWYgKChkYXRhLT5ibG9ja3MgPT0gMSkgJiYgKGNvdW50ID4gZGF0YS0+Ymxrc3opKQoJCWNvdW50ID0gZnJhbWU7CgoJaG9zdC0+ZG1hX2xlbiA9IGNvdW50OwoKCS8qIEZJRk8gaXMgMTZ4MiBieXRlcyBvbiAxNXh4LCBhbmQgMzJ4MiBieXRlcyBvbiAxNnh4IGFuZCAyNHh4LgoJICogVXNlIDE2IG9yIDMyIHdvcmQgZnJhbWVzIHdoZW4gdGhlIGJsb2Nrc2l6ZSBpcyBhdCBsZWFzdCB0aGF0IGxhcmdlLgoJICogQmxvY2tzaXplIGlzIHVzdWFsbHkgNTEyIGJ5dGVzOyBidXQgbm90IGZvciBzb21lIFNEIHJlYWRzLgoJICovCglpZiAoY3B1X2lzX29tYXAxNXh4KCkgJiYgZnJhbWUgPiAzMikKCQlmcmFtZSA9IDMyOwoJZWxzZSBpZiAoZnJhbWUgPiA2NCkKCQlmcmFtZSA9IDY0OwoJY291bnQgLz0gZnJhbWU7CglmcmFtZSA+Pj0gMTsKCglpZiAoIShkYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKSkgewoJCWJ1ZiA9IDB4ODAwZiB8ICgoZnJhbWUgLSAxKSA8PCA4KTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCXNyY19wb3J0ID0gT01BUF9ETUFfUE9SVF9USVBCOwoJCQlkc3RfcG9ydCA9IE9NQVBfRE1BX1BPUlRfRU1JRkY7CgkJfQoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQkJc3luY19kZXYgPSBPTUFQMjRYWF9ETUFfTU1DMV9SWDsKCgkJb21hcF9zZXRfZG1hX3NyY19wYXJhbXMoZG1hX2NoLCBzcmNfcG9ydCwKCQkJCQlPTUFQX0RNQV9BTU9ERV9DT05TVEFOVCwKCQkJCQlkYXRhX2FkZHIsIDAsIDApOwoJCW9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyhkbWFfY2gsIGRzdF9wb3J0LAoJCQkJCSBPTUFQX0RNQV9BTU9ERV9QT1NUX0lOQywKCQkJCQkgc2dfZG1hX2FkZHJlc3Moc2cpLCAwLCAwKTsKCQlvbWFwX3NldF9kbWFfZGVzdF9kYXRhX3BhY2soZG1hX2NoLCAxKTsKCQlvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKGRtYV9jaCwgT01BUF9ETUFfREFUQV9CVVJTVF80KTsKCX0gZWxzZSB7CgkJYnVmID0gMHgwZjgwIHwgKChmcmFtZSAtIDEpIDw8IDApOwoKCQlpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpIHsKCQkJc3JjX3BvcnQgPSBPTUFQX0RNQV9QT1JUX0VNSUZGOwoJCQlkc3RfcG9ydCA9IE9NQVBfRE1BX1BPUlRfVElQQjsKCQl9CgkJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCQlzeW5jX2RldiA9IE9NQVAyNFhYX0RNQV9NTUMxX1RYOwoKCQlvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMoZG1hX2NoLCBkc3RfcG9ydCwKCQkJCQkgT01BUF9ETUFfQU1PREVfQ09OU1RBTlQsCgkJCQkJIGRhdGFfYWRkciwgMCwgMCk7CgkJb21hcF9zZXRfZG1hX3NyY19wYXJhbXMoZG1hX2NoLCBzcmNfcG9ydCwKCQkJCQlPTUFQX0RNQV9BTU9ERV9QT1NUX0lOQywKCQkJCQlzZ19kbWFfYWRkcmVzcyhzZyksIDAsIDApOwoJCW9tYXBfc2V0X2RtYV9zcmNfZGF0YV9wYWNrKGRtYV9jaCwgMSk7CgkJb21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKGRtYV9jaCwgT01BUF9ETUFfREFUQV9CVVJTVF80KTsKCX0KCgkvKiBNYXggbGltaXQgZm9yIERNQSBmcmFtZSBjb3VudCBpcyAweGZmZmYgKi8KCUJVR19PTihjb3VudCA+IDB4ZmZmZik7CgoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQlVGLCBidWYpOwoJb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhkbWFfY2gsIE9NQVBfRE1BX0RBVEFfVFlQRV9TMTYsCgkJCQkgICAgIGZyYW1lLCBjb3VudCwgT01BUF9ETUFfU1lOQ19GUkFNRSwKCQkJCSAgICAgc3luY19kZXYsIDApOwp9CgovKiBBIHNjYXR0ZXJsaXN0IHNlZ21lbnQgY29tcGxldGVkICovCnN0YXRpYyB2b2lkIG1tY19vbWFwX2RtYV9jYihpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKSBkYXRhOwoJc3RydWN0IG1tY19kYXRhICptbWNkYXQgPSBob3N0LT5kYXRhOwoKCWlmICh1bmxpa2VseShob3N0LT5kbWFfY2ggPCAwKSkgewoJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkiRE1BIGNhbGxiYWNrIHdoaWxlIERNQSBub3QgZW5hYmxlZFxuIik7CgkJcmV0dXJuOwoJfQoJLyogRklYTUU6IFdlIHJlYWxseSBzaG91bGQgZG8gc29tZXRoaW5nIHRvIF9oYW5kbGVfIHRoZSBlcnJvcnMgKi8KCWlmIChjaF9zdGF0dXMgJiBPTUFQMV9ETUFfVE9VVF9JUlEpIHsKCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwiRE1BIHRpbWVvdXRcbiIpOwoJCXJldHVybjsKCX0KCWlmIChjaF9zdGF0dXMgJiBPTUFQX0RNQV9EUk9QX0lSUSkgewoJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLCAiRE1BIHN5bmMgZXJyb3JcbiIpOwoJCXJldHVybjsKCX0KCWlmICghKGNoX3N0YXR1cyAmIE9NQVBfRE1BX0JMT0NLX0lSUSkpIHsKCQlyZXR1cm47Cgl9CgltbWNkYXQtPmJ5dGVzX3hmZXJlZCArPSBob3N0LT5kbWFfbGVuOwoJaG9zdC0+c2dfaWR4Kys7CglpZiAoaG9zdC0+c2dfaWR4IDwgaG9zdC0+c2dfbGVuKSB7CgkJbW1jX29tYXBfcHJlcGFyZV9kbWEoaG9zdCwgaG9zdC0+ZGF0YSk7CgkJb21hcF9zdGFydF9kbWEoaG9zdC0+ZG1hX2NoKTsKCX0gZWxzZQoJCW1tY19vbWFwX2RtYV9kb25lKGhvc3QsIGhvc3QtPmRhdGEpOwp9CgpzdGF0aWMgaW50IG1tY19vbWFwX2dldF9kbWFfY2hhbm5lbChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7Cgljb25zdCBjaGFyICpkZXZfbmFtZTsKCWludCBzeW5jX2RldiwgZG1hX2NoLCBpc19yZWFkLCByOwoKCWlzX3JlYWQgPSAhKGRhdGEtPmZsYWdzICYgTU1DX0RBVEFfV1JJVEUpOwoJZGVsX3RpbWVyX3N5bmMoJmhvc3QtPmRtYV90aW1lcik7CglpZiAoaG9zdC0+ZG1hX2NoID49IDApIHsKCQlpZiAoaXNfcmVhZCA9PSBob3N0LT5kbWFfaXNfcmVhZCkKCQkJcmV0dXJuIDA7CgkJb21hcF9mcmVlX2RtYShob3N0LT5kbWFfY2gpOwoJCWhvc3QtPmRtYV9jaCA9IC0xOwoJfQoKCWlmIChpc19yZWFkKSB7CgkJaWYgKGhvc3QtPmlkID09IDEpIHsKCQkJc3luY19kZXYgPSBPTUFQX0RNQV9NTUNfUlg7CgkJCWRldl9uYW1lID0gIk1NQzEgcmVhZCI7CgkJfSBlbHNlIHsKCQkJc3luY19kZXYgPSBPTUFQX0RNQV9NTUMyX1JYOwoJCQlkZXZfbmFtZSA9ICJNTUMyIHJlYWQiOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGhvc3QtPmlkID09IDEpIHsKCQkJc3luY19kZXYgPSBPTUFQX0RNQV9NTUNfVFg7CgkJCWRldl9uYW1lID0gIk1NQzEgd3JpdGUiOwoJCX0gZWxzZSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DMl9UWDsKCQkJZGV2X25hbWUgPSAiTU1DMiB3cml0ZSI7CgkJfQoJfQoJciA9IG9tYXBfcmVxdWVzdF9kbWEoc3luY19kZXYsIGRldl9uYW1lLCBtbWNfb21hcF9kbWFfY2IsCgkJCSAgICAgaG9zdCwgJmRtYV9jaCk7CglpZiAociAhPSAwKSB7CgkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJvbWFwX3JlcXVlc3RfZG1hKCkgZmFpbGVkIHdpdGggJWRcbiIsIHIpOwoJCXJldHVybiByOwoJfQoJaG9zdC0+ZG1hX2NoID0gZG1hX2NoOwoJaG9zdC0+ZG1hX2lzX3JlYWQgPSBpc19yZWFkOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2V0X2NtZF90aW1lb3V0KHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX3JlcXVlc3QgKnJlcSkKewoJdTE2IHJlZzsKCglyZWcgPSBPTUFQX01NQ19SRUFEKGhvc3QsIFNESU8pOwoJcmVnICY9IH4oMSA8PCA1KTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIFNESU8sIHJlZyk7CgkvKiBTZXQgbWF4aW11bSB0aW1lb3V0ICovCglPTUFQX01NQ19XUklURShob3N0LCBDVE8sIDB4ZmYpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2V0X2RhdGFfdGltZW91dChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCWludCB0aW1lb3V0OwoJdTE2IHJlZzsKCgkvKiBDb252ZXJ0IG5zIHRvIGNsb2NrIGN5Y2xlcyBieSBhc3N1bWluZyAyME1IeiBmcmVxdWVuY3kKCSAqIDEgY3ljbGUgYXQgMjBNSHogPSA1MDAgbnMKCSAqLwoJdGltZW91dCA9IHJlcS0+ZGF0YS0+dGltZW91dF9jbGtzICsgcmVxLT5kYXRhLT50aW1lb3V0X25zIC8gNTAwOwoKCS8qIENoZWNrIGlmIHdlIG5lZWQgdG8gdXNlIHRpbWVvdXQgbXVsdGlwbGllciByZWdpc3RlciAqLwoJcmVnID0gT01BUF9NTUNfUkVBRChob3N0LCBTRElPKTsKCWlmICh0aW1lb3V0ID4gMHhmZmZmKSB7CgkJcmVnIHw9ICgxIDw8IDUpOwoJCXRpbWVvdXQgLz0gMTAyNDsKCX0gZWxzZQoJCXJlZyAmPSB+KDEgPDwgNSk7CglPTUFQX01NQ19XUklURShob3N0LCBTRElPLCByZWcpOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgRFRPLCB0aW1lb3V0KTsKfQoKc3RhdGljIHZvaWQKbW1jX29tYXBfcHJlcGFyZV9kYXRhKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX3JlcXVlc3QgKnJlcSkKewoJc3RydWN0IG1tY19kYXRhICpkYXRhID0gcmVxLT5kYXRhOwoJaW50IGksIHVzZV9kbWEsIGJsb2NrX3NpemU7Cgl1bnNpZ25lZCBzZ19sZW47CgoJaG9zdC0+ZGF0YSA9IGRhdGE7CglpZiAoZGF0YSA9PSBOVUxMKSB7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgQkxFTiwgMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgTkJMSywgMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgQlVGLCAwKTsKCQlob3N0LT5kbWFfaW5fdXNlID0gMDsKCQlzZXRfY21kX3RpbWVvdXQoaG9zdCwgcmVxKTsKCQlyZXR1cm47Cgl9CgoJYmxvY2tfc2l6ZSA9IGRhdGEtPmJsa3N6OwoKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIE5CTEssIGRhdGEtPmJsb2NrcyAtIDEpOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQkxFTiwgYmxvY2tfc2l6ZSAtIDEpOwoJc2V0X2RhdGFfdGltZW91dChob3N0LCByZXEpOwoKCS8qIGNvcGUgd2l0aCBjYWxsaW5nIGxheWVyIGNvbmZ1c2lvbjsgaXQgaXNzdWVzICJzaW5nbGUKCSAqIGJsb2NrIiB3cml0ZXMgdXNpbmcgbXVsdGktYmxvY2sgc2NhdHRlcmxpc3RzLgoJICovCglzZ19sZW4gPSAoZGF0YS0+YmxvY2tzID09IDEpID8gMSA6IGRhdGEtPnNnX2xlbjsKCgkvKiBPbmx5IGRvIERNQSBmb3IgZW50aXJlIGJsb2NrcyAqLwoJdXNlX2RtYSA9IGhvc3QtPnVzZV9kbWE7CglpZiAodXNlX2RtYSkgewoJCWZvciAoaSA9IDA7IGkgPCBzZ19sZW47IGkrKykgewoJCQlpZiAoKGRhdGEtPnNnW2ldLmxlbmd0aCAlIGJsb2NrX3NpemUpICE9IDApIHsKCQkJCXVzZV9kbWEgPSAwOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgoJaG9zdC0+c2dfaWR4ID0gMDsKCWlmICh1c2VfZG1hKSB7CgkJaWYgKG1tY19vbWFwX2dldF9kbWFfY2hhbm5lbChob3N0LCBkYXRhKSA9PSAwKSB7CgkJCWVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRtYV9kYXRhX2RpcjsKCgkJCWlmIChkYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKQoJCQkJZG1hX2RhdGFfZGlyID0gRE1BX1RPX0RFVklDRTsKCQkJZWxzZQoJCQkJZG1hX2RhdGFfZGlyID0gRE1BX0ZST01fREVWSUNFOwoKCQkJaG9zdC0+c2dfbGVuID0gZG1hX21hcF9zZyhtbWNfZGV2KGhvc3QtPm1tYyksIGRhdGEtPnNnLAoJCQkJCQlzZ19sZW4sIGRtYV9kYXRhX2Rpcik7CgkJCWhvc3QtPnRvdGFsX2J5dGVzX2xlZnQgPSAwOwoJCQltbWNfb21hcF9wcmVwYXJlX2RtYShob3N0LCByZXEtPmRhdGEpOwoJCQlob3N0LT5icnNfcmVjZWl2ZWQgPSAwOwoJCQlob3N0LT5kbWFfZG9uZSA9IDA7CgkJCWhvc3QtPmRtYV9pbl91c2UgPSAxOwoJCX0gZWxzZQoJCQl1c2VfZG1hID0gMDsKCX0KCgkvKiBSZXZlcnQgdG8gUElPPyAqLwoJaWYgKCF1c2VfZG1hKSB7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgQlVGLCAweDFmMWYpOwoJCWhvc3QtPnRvdGFsX2J5dGVzX2xlZnQgPSBkYXRhLT5ibG9ja3MgKiBibG9ja19zaXplOwoJCWhvc3QtPnNnX2xlbiA9IHNnX2xlbjsKCQltbWNfb21hcF9zZ190b19idWYoaG9zdCk7CgkJaG9zdC0+ZG1hX2luX3VzZSA9IDA7Cgl9Cn0KCnN0YXRpYyB2b2lkIG1tY19vbWFwX3JlcXVlc3Qoc3RydWN0IG1tY19ob3N0ICptbWMsIHN0cnVjdCBtbWNfcmVxdWVzdCAqcmVxKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IG1tY19wcml2KG1tYyk7CgoJV0FSTl9PTihob3N0LT5tcnEgIT0gTlVMTCk7CgoJaG9zdC0+bXJxID0gcmVxOwoKCS8qIG9ubHkgdG91Y2ggZmlmbyBBRlRFUiB0aGUgY29udHJvbGxlciByZWFkaWVzIGl0ICovCgltbWNfb21hcF9wcmVwYXJlX2RhdGEoaG9zdCwgcmVxKTsKCW1tY19vbWFwX3N0YXJ0X2NvbW1hbmQoaG9zdCwgcmVxLT5jbWQpOwoJaWYgKGhvc3QtPmRtYV9pbl91c2UpCgkJb21hcF9zdGFydF9kbWEoaG9zdC0+ZG1hX2NoKTsKfQoKc3RhdGljIHZvaWQgaW5ub3ZhdG9yX2ZwZ2Ffc29ja2V0X3Bvd2VyKGludCBvbikKewojaWYgZGVmaW5lZChDT05GSUdfTUFDSF9PTUFQX0lOTk9WQVRPUikgJiYgZGVmaW5lZChDT05GSUdfQVJDSF9PTUFQMTVYWCkKCWlmIChvbikgewoJCWZwZ2Ffd3JpdGUoZnBnYV9yZWFkKE9NQVAxNTEwX0ZQR0FfUE9XRVIpIHwgKDEgPDwgMyksCgkJICAgICBPTUFQMTUxMF9GUEdBX1BPV0VSKTsKCX0gZWxzZSB7CgkJZnBnYV93cml0ZShmcGdhX3JlYWQoT01BUDE1MTBfRlBHQV9QT1dFUikgJiB+KDEgPDwgMyksCgkJICAgICBPTUFQMTUxMF9GUEdBX1BPV0VSKTsKCX0KI2VuZGlmCn0KCi8qCiAqIFR1cm4gdGhlIHNvY2tldCBwb3dlciBvbi9vZmYuIElubm92YXRvciB1c2VzIEZQR0EsIG1vc3QgYm9hcmRzCiAqIHByb2JhYmx5IHVzZSBHUElPLgogKi8Kc3RhdGljIHZvaWQgbW1jX29tYXBfcG93ZXIoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIGludCBvbikKewoJaWYgKG9uKSB7CgkJaWYgKG1hY2hpbmVfaXNfb21hcF9pbm5vdmF0b3IoKSkKCQkJaW5ub3ZhdG9yX2ZwZ2Ffc29ja2V0X3Bvd2VyKDEpOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMigpKQoJCQl0cHM2NTAxMF9zZXRfZ3Bpb19vdXRfdmFsdWUoR1BJTzMsIEhJR0gpOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMygpKQoJCQkvKiBHUElPIDQgb2YgVFBTNjUwMTAgc2VuZHMgU0RfRU4gc2lnbmFsICovCgkJCXRwczY1MDEwX3NldF9ncGlvX291dF92YWx1ZShHUElPNCwgSElHSCk7CgkJZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkJdTE2IHJlZyA9IE9NQVBfTU1DX1JFQUQoaG9zdCwgQ09OKTsKCQkJT01BUF9NTUNfV1JJVEUoaG9zdCwgQ09OLCByZWcgfCAoMSA8PCAxMSkpOwoJCX0gZWxzZQoJCQlpZiAoaG9zdC0+cG93ZXJfcGluID49IDApCgkJCQlvbWFwX3NldF9ncGlvX2RhdGFvdXQoaG9zdC0+cG93ZXJfcGluLCAxKTsKCX0gZWxzZSB7CgkJaWYgKG1hY2hpbmVfaXNfb21hcF9pbm5vdmF0b3IoKSkKCQkJaW5ub3ZhdG9yX2ZwZ2Ffc29ja2V0X3Bvd2VyKDApOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMigpKQoJCQl0cHM2NTAxMF9zZXRfZ3Bpb19vdXRfdmFsdWUoR1BJTzMsIExPVyk7CgkJZWxzZSBpZiAobWFjaGluZV9pc19vbWFwX2gzKCkpCgkJCXRwczY1MDEwX3NldF9ncGlvX291dF92YWx1ZShHUElPNCwgTE9XKTsKCQllbHNlIGlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCQl1MTYgcmVnID0gT01BUF9NTUNfUkVBRChob3N0LCBDT04pOwoJCQlPTUFQX01NQ19XUklURShob3N0LCBDT04sIHJlZyAmIH4oMSA8PCAxMSkpOwoJCX0gZWxzZQoJCQlpZiAoaG9zdC0+cG93ZXJfcGluID49IDApCgkJCQlvbWFwX3NldF9ncGlvX2RhdGFvdXQoaG9zdC0+cG93ZXJfcGluLCAwKTsKCX0KfQoKc3RhdGljIGludCBtbWNfb21hcF9jYWxjX2Rpdmlzb3Ioc3RydWN0IG1tY19ob3N0ICptbWMsIHN0cnVjdCBtbWNfaW9zICppb3MpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gbW1jX3ByaXYobW1jKTsKCWludCBmdW5jX2Nsa19yYXRlID0gY2xrX2dldF9yYXRlKGhvc3QtPmZjbGspOwoJaW50IGRzb3I7CgoJaWYgKGlvcy0+Y2xvY2sgPT0gMCkKCQlyZXR1cm4gMDsKCglkc29yID0gZnVuY19jbGtfcmF0ZSAvIGlvcy0+Y2xvY2s7CglpZiAoZHNvciA8IDEpCgkJZHNvciA9IDE7CgoJaWYgKGZ1bmNfY2xrX3JhdGUgLyBkc29yID4gaW9zLT5jbG9jaykKCQlkc29yKys7CgoJaWYgKGRzb3IgPiAyNTApCgkJZHNvciA9IDI1MDsKCWRzb3IrKzsKCglpZiAoaW9zLT5idXNfd2lkdGggPT0gTU1DX0JVU19XSURUSF80KQoJCWRzb3IgfD0gMSA8PCAxNTsKCglyZXR1cm4gZHNvcjsKfQoKc3RhdGljIHZvaWQgbW1jX29tYXBfc2V0X2lvcyhzdHJ1Y3QgbW1jX2hvc3QgKm1tYywgc3RydWN0IG1tY19pb3MgKmlvcykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBtbWNfcHJpdihtbWMpOwoJaW50IGRzb3I7CglpbnQgaTsKCglkc29yID0gbW1jX29tYXBfY2FsY19kaXZpc29yKG1tYywgaW9zKTsKCWhvc3QtPmJ1c19tb2RlID0gaW9zLT5idXNfbW9kZTsKCWhvc3QtPmh3X2J1c19tb2RlID0gaG9zdC0+YnVzX21vZGU7CgoJc3dpdGNoIChpb3MtPnBvd2VyX21vZGUpIHsKCWNhc2UgTU1DX1BPV0VSX09GRjoKCQltbWNfb21hcF9wb3dlcihob3N0LCAwKTsKCQlicmVhazsKCWNhc2UgTU1DX1BPV0VSX1VQOgoJCS8qIENhbm5vdCB0b3VjaCBkc29yIHlldCwganVzdCBwb3dlciB1cCBNTUMgKi8KCQltbWNfb21hcF9wb3dlcihob3N0LCAxKTsKCQlyZXR1cm47CgljYXNlIE1NQ19QT1dFUl9PTjoKCQlkc29yIHw9IDEgPDwgMTE7CgkJYnJlYWs7Cgl9CgoJY2xrX2VuYWJsZShob3N0LT5mY2xrKTsKCgkvKiBPbiBpbnNhbmVseSBoaWdoIGFybV9wZXIgZnJlcXVlbmNpZXMgc29tZXRoaW5nIHNvbWV0aW1lcwoJICogZ29lcyBzb21laG93IG91dCBvZiBzeW5jLCBhbmQgdGhlIFBPVyBiaXQgaXMgbm90IGJlaW5nIHNldCwKCSAqIHdoaWNoIHJlc3VsdHMgaW4gdGhlIHdoaWxlIGxvb3AgYmVsb3cgZ2V0dGluZyBzdHVjay4KCSAqIFdyaXRpbmcgdG8gdGhlIENPTiByZWdpc3RlciB0d2ljZSBzZWVtcyB0byBkbyB0aGUgdHJpY2suICovCglmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKQoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIENPTiwgZHNvcik7CglpZiAoaW9zLT5wb3dlcl9tb2RlID09IE1NQ19QT1dFUl9PTikgewoJCS8qIFNlbmQgY2xvY2sgY3ljbGVzLCBwb2xsIGNvbXBsZXRpb24gKi8KCQlPTUFQX01NQ19XUklURShob3N0LCBJRSwgMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgU1RBVCwgMHhmZmZmKTsKCQlPTUFQX01NQ19XUklURShob3N0LCBDTUQsIDEgPDwgNyk7CgkJd2hpbGUgKChPTUFQX01NQ19SRUFEKGhvc3QsIFNUQVQpICYgMSkgPT0gMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgU1RBVCwgMSk7Cgl9CgljbGtfZGlzYWJsZShob3N0LT5mY2xrKTsKfQoKc3RhdGljIGludCBtbWNfb21hcF9nZXRfcm8oc3RydWN0IG1tY19ob3N0ICptbWMpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gbW1jX3ByaXYobW1jKTsKCglyZXR1cm4gaG9zdC0+d3BfcGluICYmIG9tYXBfZ2V0X2dwaW9fZGF0YWluKGhvc3QtPndwX3Bpbik7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgbW1jX2hvc3Rfb3BzIG1tY19vbWFwX29wcyA9IHsKCS5yZXF1ZXN0CT0gbW1jX29tYXBfcmVxdWVzdCwKCS5zZXRfaW9zCT0gbW1jX29tYXBfc2V0X2lvcywKCS5nZXRfcm8JCT0gbW1jX29tYXBfZ2V0X3JvLAp9OwoKc3RhdGljIGludCBfX2luaXQgbW1jX29tYXBfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKewoJc3RydWN0IG9tYXBfbW1jX2NvbmYgKm1pbmZvID0gcGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CglzdHJ1Y3QgbW1jX2hvc3QgKm1tYzsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gTlVMTDsKCXN0cnVjdCByZXNvdXJjZSAqcmVzOwoJaW50IHJldCA9IDA7CglpbnQgaXJxOwoKCWlmIChtaW5mbyA9PSBOVUxMKSB7CgkJZGV2X2VycigmcGRldi0+ZGV2LCAicGxhdGZvcm0gZGF0YSBtaXNzaW5nXG4iKTsKCQlyZXR1cm4gLUVOWElPOwoJfQoKCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7CglpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwoJaWYgKHJlcyA9PSBOVUxMIHx8IGlycSA8IDApCgkJcmV0dXJuIC1FTlhJTzsKCglyZXMgPSByZXF1ZXN0X21lbV9yZWdpb24ocmVzLT5zdGFydCwgcmVzLT5lbmQgLSByZXMtPnN0YXJ0ICsgMSwKCQkJICAgICAgICAgcGRldi0+bmFtZSk7CglpZiAocmVzID09IE5VTEwpCgkJcmV0dXJuIC1FQlVTWTsKCgltbWMgPSBtbWNfYWxsb2NfaG9zdChzaXplb2Yoc3RydWN0IG1tY19vbWFwX2hvc3QpLCAmcGRldi0+ZGV2KTsKCWlmIChtbWMgPT0gTlVMTCkgewoJCXJldCA9IC1FTk9NRU07CgkJZ290byBlcnJfZnJlZV9tZW1fcmVnaW9uOwoJfQoKCWhvc3QgPSBtbWNfcHJpdihtbWMpOwoJaG9zdC0+bW1jID0gbW1jOwoKCXNwaW5fbG9ja19pbml0KCZob3N0LT5kbWFfbG9jayk7Cglpbml0X3RpbWVyKCZob3N0LT5kbWFfdGltZXIpOwoJaG9zdC0+ZG1hX3RpbWVyLmZ1bmN0aW9uID0gbW1jX29tYXBfZG1hX3RpbWVyOwoJaG9zdC0+ZG1hX3RpbWVyLmRhdGEgPSAodW5zaWduZWQgbG9uZykgaG9zdDsKCglob3N0LT5pZCA9IHBkZXYtPmlkOwoJaG9zdC0+bWVtX3JlcyA9IHJlczsKCWhvc3QtPmlycSA9IGlycTsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlob3N0LT5pY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2ljayIpOwoJCWlmIChJU19FUlIoaG9zdC0+aWNsaykpCgkJCWdvdG8gZXJyX2ZyZWVfbW1jX2hvc3Q7CgkJY2xrX2VuYWJsZShob3N0LT5pY2xrKTsKCX0KCglpZiAoIWNwdV9pc19vbWFwMjR4eCgpKQoJCWhvc3QtPmZjbGsgPSBjbGtfZ2V0KCZwZGV2LT5kZXYsICJtbWNfY2siKTsKCWVsc2UKCQlob3N0LT5mY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2ZjayIpOwoKCWlmIChJU19FUlIoaG9zdC0+ZmNsaykpIHsKCQlyZXQgPSBQVFJfRVJSKGhvc3QtPmZjbGspOwoJCWdvdG8gZXJyX2ZyZWVfaWNsazsKCX0KCgkvKiBSRVZJU0lUOgoJICogQWxzbywgdXNlIG1pbmZvLT5jb3ZlciB0byBkZWNpZGUgaG93IHRvIG1hbmFnZQoJICogdGhlIGNhcmQgZGV0ZWN0IHNlbnNpbmcuCgkgKi8KCWhvc3QtPnBvd2VyX3BpbiA9IG1pbmZvLT5wb3dlcl9waW47Cglob3N0LT5zd2l0Y2hfcGluID0gbWluZm8tPnN3aXRjaF9waW47Cglob3N0LT53cF9waW4gPSBtaW5mby0+d3BfcGluOwoJaG9zdC0+dXNlX2RtYSA9IDE7Cglob3N0LT5kbWFfY2ggPSAtMTsKCglob3N0LT5pcnEgPSBpcnE7Cglob3N0LT5waHlzX2Jhc2UgPSBob3N0LT5tZW1fcmVzLT5zdGFydDsKCWhvc3QtPnZpcnRfYmFzZSA9ICh2b2lkIF9faW9tZW0gKikgSU9fQUREUkVTUyhob3N0LT5waHlzX2Jhc2UpOwoKCW1tYy0+b3BzID0gJm1tY19vbWFwX29wczsKCW1tYy0+Zl9taW4gPSA0MDAwMDA7CgltbWMtPmZfbWF4ID0gMjQwMDAwMDA7CgltbWMtPm9jcl9hdmFpbCA9IE1NQ19WRERfMzJfMzMgfCBNTUNfVkREXzMzXzM0OwoJbW1jLT5jYXBzID0gTU1DX0NBUF9NVUxUSVdSSVRFIHwgTU1DX0NBUF9CWVRFQkxPQ0s7CgoJaWYgKG1pbmZvLT53aXJlNCkKCQkgbW1jLT5jYXBzIHw9IE1NQ19DQVBfNF9CSVRfREFUQTsKCgkvKiBVc2Ugc2NhdHRlcmxpc3QgRE1BIHRvIHJlZHVjZSBwZXItdHJhbnNmZXIgY29zdHMuCgkgKiBOT1RFIG1heF9zZWdfc2l6ZSBhc3N1bXB0aW9uIHRoYXQgc21hbGwgYmxvY2tzIGFyZW4ndAoJICogbm9ybWFsbHkgdXNlZCAoZXhjZXB0IGUuZy4gZm9yIHJlYWRpbmcgU0QgcmVnaXN0ZXJzKS4KCSAqLwoJbW1jLT5tYXhfcGh5c19zZWdzID0gMzI7CgltbWMtPm1heF9od19zZWdzID0gMzI7CgltbWMtPm1heF9ibGtfc2l6ZSA9IDIwNDg7CS8qIEJMRU4gaXMgMTEgYml0cyAoKzEpICovCgltbWMtPm1heF9ibGtfY291bnQgPSAyMDQ4OwkvKiBOQkxLIGlzIDExIGJpdHMgKCsxKSAqLwoJbW1jLT5tYXhfcmVxX3NpemUgPSBtbWMtPm1heF9ibGtfc2l6ZSAqIG1tYy0+bWF4X2Jsa19jb3VudDsKCW1tYy0+bWF4X3NlZ19zaXplID0gbW1jLT5tYXhfcmVxX3NpemU7CgoJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKSB7CgkJaWYgKChyZXQgPSBvbWFwX3JlcXVlc3RfZ3Bpbyhob3N0LT5wb3dlcl9waW4pKSAhPSAwKSB7CgkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJIlVuYWJsZSB0byBnZXQgR1BJTyBwaW4gZm9yIE1NQyBwb3dlclxuIik7CgkJCWdvdG8gZXJyX2ZyZWVfZmNsazsKCQl9CgkJb21hcF9zZXRfZ3Bpb19kaXJlY3Rpb24oaG9zdC0+cG93ZXJfcGluLCAwKTsKCX0KCglyZXQgPSByZXF1ZXN0X2lycShob3N0LT5pcnEsIG1tY19vbWFwX2lycSwgMCwgRFJJVkVSX05BTUUsIGhvc3QpOwoJaWYgKHJldCkKCQlnb3RvIGVycl9mcmVlX3Bvd2VyX2dwaW87CgoJaG9zdC0+ZGV2ID0gJnBkZXYtPmRldjsKCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGhvc3QpOwoKCWlmIChob3N0LT5zd2l0Y2hfcGluID49IDApIHsKCQlJTklUX1dPUksoJmhvc3QtPnN3aXRjaF93b3JrLCBtbWNfb21hcF9zd2l0Y2hfaGFuZGxlcik7CgkJaW5pdF90aW1lcigmaG9zdC0+c3dpdGNoX3RpbWVyKTsKCQlob3N0LT5zd2l0Y2hfdGltZXIuZnVuY3Rpb24gPSBtbWNfb21hcF9zd2l0Y2hfdGltZXI7CgkJaG9zdC0+c3dpdGNoX3RpbWVyLmRhdGEgPSAodW5zaWduZWQgbG9uZykgaG9zdDsKCQlpZiAob21hcF9yZXF1ZXN0X2dwaW8oaG9zdC0+c3dpdGNoX3BpbikgIT0gMCkgewoJCQlkZXZfd2FybihtbWNfZGV2KGhvc3QtPm1tYyksICJVbmFibGUgdG8gZ2V0IEdQSU8gcGluIGZvciBNTUMgY292ZXIgc3dpdGNoXG4iKTsKCQkJaG9zdC0+c3dpdGNoX3BpbiA9IC0xOwoJCQlnb3RvIG5vX3N3aXRjaDsKCQl9CgoJCW9tYXBfc2V0X2dwaW9fZGlyZWN0aW9uKGhvc3QtPnN3aXRjaF9waW4sIDEpOwoJCXJldCA9IHJlcXVlc3RfaXJxKE9NQVBfR1BJT19JUlEoaG9zdC0+c3dpdGNoX3BpbiksCgkJCQkgIG1tY19vbWFwX3N3aXRjaF9pcnEsIElSUUZfVFJJR0dFUl9SSVNJTkcsIERSSVZFUl9OQU1FLCBob3N0KTsKCQlpZiAocmV0KSB7CgkJCWRldl93YXJuKG1tY19kZXYoaG9zdC0+bW1jKSwgIlVuYWJsZSB0byBnZXQgSVJRIGZvciBNTUMgY292ZXIgc3dpdGNoXG4iKTsKCQkJb21hcF9mcmVlX2dwaW8oaG9zdC0+c3dpdGNoX3Bpbik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZ290byBub19zd2l0Y2g7CgkJfQoJCXJldCA9IGRldmljZV9jcmVhdGVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQlpZiAocmV0ID09IDApIHsKCQkJcmV0ID0gZGV2aWNlX2NyZWF0ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9lbmFibGVfcG9sbCk7CgkJCWlmIChyZXQgIT0gMCkKCQkJCWRldmljZV9yZW1vdmVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQl9CgkJaWYgKHJldCkgewoJCQlkZXZfd2FybihtbWNfZGV2KGhvc3QtPm1tYyksICJVbmFibGUgdG8gY3JlYXRlIHN5c2ZzIGF0dHJpYnV0ZXNcbiIpOwoJCQlmcmVlX2lycShPTUFQX0dQSU9fSVJRKGhvc3QtPnN3aXRjaF9waW4pLCBob3N0KTsKCQkJb21hcF9mcmVlX2dwaW8oaG9zdC0+c3dpdGNoX3Bpbik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZ290byBub19zd2l0Y2g7CgkJfQoJCWlmIChtbWNfb21hcF9lbmFibGVfcG9sbCAmJiBtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpKQoJCQlzY2hlZHVsZV93b3JrKCZob3N0LT5zd2l0Y2hfd29yayk7Cgl9CgoJbW1jX2FkZF9ob3N0KG1tYyk7CgoJcmV0dXJuIDA7Cgpub19zd2l0Y2g6CgkvKiBGSVhNRTogRnJlZSBvdGhlciByZXNvdXJjZXMgdG9vLiAqLwoJaWYgKGhvc3QpIHsKCQlpZiAoaG9zdC0+aWNsayAmJiAhSVNfRVJSKGhvc3QtPmljbGspKQoJCQljbGtfcHV0KGhvc3QtPmljbGspOwoJCWlmIChob3N0LT5mY2xrICYmICFJU19FUlIoaG9zdC0+ZmNsaykpCgkJCWNsa19wdXQoaG9zdC0+ZmNsayk7CgkJbW1jX2ZyZWVfaG9zdChob3N0LT5tbWMpOwoJfQplcnJfZnJlZV9wb3dlcl9ncGlvOgoJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKQoJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnBvd2VyX3Bpbik7CmVycl9mcmVlX2ZjbGs6CgljbGtfcHV0KGhvc3QtPmZjbGspOwplcnJfZnJlZV9pY2xrOgoJaWYgKGhvc3QtPmljbGsgIT0gTlVMTCkgewoJCWNsa19kaXNhYmxlKGhvc3QtPmljbGspOwoJCWNsa19wdXQoaG9zdC0+aWNsayk7Cgl9CmVycl9mcmVlX21tY19ob3N0OgoJbW1jX2ZyZWVfaG9zdChob3N0LT5tbWMpOwplcnJfZnJlZV9tZW1fcmVnaW9uOgoJcmVsZWFzZV9tZW1fcmVnaW9uKHJlcy0+c3RhcnQsIHJlcy0+ZW5kIC0gcmVzLT5zdGFydCArIDEpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBtbWNfb21hcF9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKCglwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKCglCVUdfT04oaG9zdCA9PSBOVUxMKTsKCgltbWNfcmVtb3ZlX2hvc3QoaG9zdC0+bW1jKTsKCWZyZWVfaXJxKGhvc3QtPmlycSwgaG9zdCk7CgoJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKQoJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnBvd2VyX3Bpbik7CglpZiAoaG9zdC0+c3dpdGNoX3BpbiA+PSAwKSB7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9lbmFibGVfcG9sbCk7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9jb3Zlcl9zd2l0Y2gpOwoJCWZyZWVfaXJxKE9NQVBfR1BJT19JUlEoaG9zdC0+c3dpdGNoX3BpbiksIGhvc3QpOwoJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnN3aXRjaF9waW4pOwoJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQlkZWxfdGltZXJfc3luYygmaG9zdC0+c3dpdGNoX3RpbWVyKTsKCQlmbHVzaF9zY2hlZHVsZWRfd29yaygpOwoJfQoJaWYgKGhvc3QtPmljbGsgJiYgIUlTX0VSUihob3N0LT5pY2xrKSkKCQljbGtfcHV0KGhvc3QtPmljbGspOwoJaWYgKGhvc3QtPmZjbGsgJiYgIUlTX0VSUihob3N0LT5mY2xrKSkKCQljbGtfcHV0KGhvc3QtPmZjbGspOwoKCXJlbGVhc2VfbWVtX3JlZ2lvbihwZGV2LT5yZXNvdXJjZVswXS5zdGFydCwKCQkJICAgcGRldi0+cmVzb3VyY2VbMF0uZW5kIC0gcGRldi0+cmVzb3VyY2VbMF0uc3RhcnQgKyAxKTsKCgltbWNfZnJlZV9ob3N0KGhvc3QtPm1tYyk7CgoJcmV0dXJuIDA7Cn0KCiNpZmRlZiBDT05GSUdfUE0Kc3RhdGljIGludCBtbWNfb21hcF9zdXNwZW5kKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsIHBtX21lc3NhZ2VfdCBtZXNnKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CgoJaWYgKGhvc3QgJiYgaG9zdC0+c3VzcGVuZGVkKQoJCXJldHVybiAwOwoKCWlmIChob3N0KSB7CgkJcmV0ID0gbW1jX3N1c3BlbmRfaG9zdChob3N0LT5tbWMsIG1lc2cpOwoJCWlmIChyZXQgPT0gMCkKCQkJaG9zdC0+c3VzcGVuZGVkID0gMTsKCX0KCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgbW1jX29tYXBfcmVzdW1lKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCWludCByZXQgPSAwOwoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKCglpZiAoaG9zdCAmJiAhaG9zdC0+c3VzcGVuZGVkKQoJCXJldHVybiAwOwoKCWlmIChob3N0KSB7CgkJcmV0ID0gbW1jX3Jlc3VtZV9ob3N0KGhvc3QtPm1tYyk7CgkJaWYgKHJldCA9PSAwKQoJCQlob3N0LT5zdXNwZW5kZWQgPSAwOwoJfQoKCXJldHVybiByZXQ7Cn0KI2Vsc2UKI2RlZmluZSBtbWNfb21hcF9zdXNwZW5kCU5VTEwKI2RlZmluZSBtbWNfb21hcF9yZXN1bWUJCU5VTEwKI2VuZGlmCgpzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBtbWNfb21hcF9kcml2ZXIgPSB7CgkucHJvYmUJCT0gbW1jX29tYXBfcHJvYmUsCgkucmVtb3ZlCQk9IG1tY19vbWFwX3JlbW92ZSwKCS5zdXNwZW5kCT0gbW1jX29tYXBfc3VzcGVuZCwKCS5yZXN1bWUJCT0gbW1jX29tYXBfcmVzdW1lLAoJLmRyaXZlcgkJPSB7CgkJLm5hbWUJPSBEUklWRVJfTkFNRSwKCX0sCn07CgpzdGF0aWMgaW50IF9faW5pdCBtbWNfb21hcF9pbml0KHZvaWQpCnsKCXJldHVybiBwbGF0Zm9ybV9kcml2ZXJfcmVnaXN0ZXIoJm1tY19vbWFwX2RyaXZlcik7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBtbWNfb21hcF9leGl0KHZvaWQpCnsKCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZtbWNfb21hcF9kcml2ZXIpOwp9Cgptb2R1bGVfaW5pdChtbWNfb21hcF9pbml0KTsKbW9kdWxlX2V4aXQobW1jX29tYXBfZXhpdCk7CgpNT0RVTEVfREVTQ1JJUFRJT04oIk9NQVAgTXVsdGltZWRpYSBDYXJkIGRyaXZlciIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BTElBUyhEUklWRVJfTkFNRSk7Ck1PRFVMRV9BVVRIT1IoIkp1aGEgWXJq9mzkIik7Cg==