LyoKICogIGxpbnV4L2RyaXZlcnMvbW1jL2hvc3Qvb21hcC5jCiAqCiAqICBDb3B5cmlnaHQgKEMpIDIwMDQgTm9raWEgQ29ycG9yYXRpb24KICogIFdyaXR0ZW4gYnkgVHV1a2thIFRpa2thbmVuIGFuZCBKdWhhIFlyavZs5DxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqICBNaXNjIGhhY2tzIGhlcmUgYW5kIHRoZXJlIGJ5IFRvbnkgTGluZGdyZW4gPHRvbnlAYXRvbWlkZS5jb20+CiAqICBPdGhlciBoYWNrcyAoRE1BLCBTRCwgZXRjKSBieSBEYXZpZCBCcm93bmVsbAogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGVwYXJhbS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zcGlubG9jay5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L21tYy9ob3N0Lmg+CiNpbmNsdWRlIDxsaW51eC9tbWMvY2FyZC5oPgojaW5jbHVkZSA8bGludXgvY2xrLmg+CiNpbmNsdWRlIDxsaW51eC9zY2F0dGVybGlzdC5oPgojaW5jbHVkZSA8bGludXgvaTJjL3RwczY1MDEwLmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vbWFjaC10eXBlcy5oPgoKI2luY2x1ZGUgPGFzbS9hcmNoL2JvYXJkLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9ncGlvLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9kbWEuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL211eC5oPgojaW5jbHVkZSA8YXNtL2FyY2gvZnBnYS5oPgoKI2RlZmluZQlPTUFQX01NQ19SRUdfQ01ECTB4MDAKI2RlZmluZQlPTUFQX01NQ19SRUdfQVJHTAkweDA0CiNkZWZpbmUJT01BUF9NTUNfUkVHX0FSR0gJMHgwOAojZGVmaW5lCU9NQVBfTU1DX1JFR19DT04JMHgwYwojZGVmaW5lCU9NQVBfTU1DX1JFR19TVEFUCTB4MTAKI2RlZmluZQlPTUFQX01NQ19SRUdfSUUJCTB4MTQKI2RlZmluZQlPTUFQX01NQ19SRUdfQ1RPCTB4MTgKI2RlZmluZQlPTUFQX01NQ19SRUdfRFRPCTB4MWMKI2RlZmluZQlPTUFQX01NQ19SRUdfREFUQQkweDIwCiNkZWZpbmUJT01BUF9NTUNfUkVHX0JMRU4JMHgyNAojZGVmaW5lCU9NQVBfTU1DX1JFR19OQkxLCTB4MjgKI2RlZmluZQlPTUFQX01NQ19SRUdfQlVGCTB4MmMKI2RlZmluZSBPTUFQX01NQ19SRUdfU0RJTwkweDM0CiNkZWZpbmUJT01BUF9NTUNfUkVHX1JFVgkweDNjCiNkZWZpbmUJT01BUF9NTUNfUkVHX1JTUDAJMHg0MAojZGVmaW5lCU9NQVBfTU1DX1JFR19SU1AxCTB4NDQKI2RlZmluZQlPTUFQX01NQ19SRUdfUlNQMgkweDQ4CiNkZWZpbmUJT01BUF9NTUNfUkVHX1JTUDMJMHg0YwojZGVmaW5lCU9NQVBfTU1DX1JFR19SU1A0CTB4NTAKI2RlZmluZQlPTUFQX01NQ19SRUdfUlNQNQkweDU0CiNkZWZpbmUJT01BUF9NTUNfUkVHX1JTUDYJMHg1OAojZGVmaW5lCU9NQVBfTU1DX1JFR19SU1A3CTB4NWMKI2RlZmluZQlPTUFQX01NQ19SRUdfSU9TUgkweDYwCiNkZWZpbmUJT01BUF9NTUNfUkVHX1NZU0MJMHg2NAojZGVmaW5lCU9NQVBfTU1DX1JFR19TWVNTCTB4NjgKCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9DQVJEX0VSUgkJKDEgPDwgMTQpCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9DQVJEX0lSUQkJKDEgPDwgMTMpCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9PQ1JfQlVTWQkJKDEgPDwgMTIpCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9BX0VNUFRZCQkoMSA8PCAxMSkKI2RlZmluZQlPTUFQX01NQ19TVEFUX0FfRlVMTAkJKDEgPDwgMTApCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9DTURfQ1JDCQkoMSA8PCAgOCkKI2RlZmluZQlPTUFQX01NQ19TVEFUX0NNRF9UT1VUCQkoMSA8PCAgNykKI2RlZmluZQlPTUFQX01NQ19TVEFUX0RBVEFfQ1JDCQkoMSA8PCAgNikKI2RlZmluZQlPTUFQX01NQ19TVEFUX0RBVEFfVE9VVAkJKDEgPDwgIDUpCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9FTkRfQlVTWQkJKDEgPDwgIDQpCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9FTkRfT0ZfREFUQQkoMSA8PCAgMykKI2RlZmluZQlPTUFQX01NQ19TVEFUX0NBUkRfQlVTWQkJKDEgPDwgIDIpCiNkZWZpbmUJT01BUF9NTUNfU1RBVF9FTkRfT0ZfQ01ECSgxIDw8ICAwKQoKI2RlZmluZSBPTUFQX01NQ19SRUFEKGhvc3QsIHJlZykJX19yYXdfcmVhZHcoKGhvc3QpLT52aXJ0X2Jhc2UgKyBPTUFQX01NQ19SRUdfIyNyZWcpCiNkZWZpbmUgT01BUF9NTUNfV1JJVEUoaG9zdCwgcmVnLCB2YWwpCV9fcmF3X3dyaXRldygodmFsKSwgKGhvc3QpLT52aXJ0X2Jhc2UgKyBPTUFQX01NQ19SRUdfIyNyZWcpCgovKgogKiBDb21tYW5kIHR5cGVzCiAqLwojZGVmaW5lIE9NQVBfTU1DX0NNRFRZUEVfQkMJMAojZGVmaW5lIE9NQVBfTU1DX0NNRFRZUEVfQkNSCTEKI2RlZmluZSBPTUFQX01NQ19DTURUWVBFX0FDCTIKI2RlZmluZSBPTUFQX01NQ19DTURUWVBFX0FEVEMJMwoKCiNkZWZpbmUgRFJJVkVSX05BTUUgIm1tY2ktb21hcCIKCi8qIFNwZWNpZmllcyBob3cgb2Z0ZW4gaW4gbWlsbGlzZWNzIHRvIHBvbGwgZm9yIGNhcmQgc3RhdHVzIGNoYW5nZXMKICogd2hlbiB0aGUgY292ZXIgc3dpdGNoIGlzIG9wZW4gKi8KI2RlZmluZSBPTUFQX01NQ19TV0lUQ0hfUE9MTF9ERUxBWQk1MDAKCnN0YXRpYyBpbnQgbW1jX29tYXBfZW5hYmxlX3BvbGwgPSAxOwoKc3RydWN0IG1tY19vbWFwX2hvc3QgewoJaW50CQkJaW5pdGlhbGl6ZWQ7CglpbnQJCQlzdXNwZW5kZWQ7CglzdHJ1Y3QgbW1jX3JlcXVlc3QgKgltcnE7CglzdHJ1Y3QgbW1jX2NvbW1hbmQgKgljbWQ7CglzdHJ1Y3QgbW1jX2RhdGEgKglkYXRhOwoJc3RydWN0IG1tY19ob3N0ICoJbW1jOwoJc3RydWN0IGRldmljZSAqCQlkZXY7Cgl1bnNpZ25lZCBjaGFyCQlpZDsgLyogMTZ4eCBjaGlwcyBoYXZlIDIgTU1DIGJsb2NrcyAqLwoJc3RydWN0IGNsayAqCQlpY2xrOwoJc3RydWN0IGNsayAqCQlmY2xrOwoJc3RydWN0IHJlc291cmNlCQkqbWVtX3JlczsKCXZvaWQgX19pb21lbQkJKnZpcnRfYmFzZTsKCXVuc2lnbmVkIGludAkJcGh5c19iYXNlOwoJaW50CQkJaXJxOwoJdW5zaWduZWQgY2hhcgkJYnVzX21vZGU7Cgl1bnNpZ25lZCBjaGFyCQlod19idXNfbW9kZTsKCgl1bnNpZ25lZCBpbnQJCXNnX2xlbjsKCWludAkJCXNnX2lkeDsKCXUxNiAqCQkJYnVmZmVyOwoJdTMyCQkJYnVmZmVyX2J5dGVzX2xlZnQ7Cgl1MzIJCQl0b3RhbF9ieXRlc19sZWZ0OwoKCXVuc2lnbmVkCQl1c2VfZG1hOjE7Cgl1bnNpZ25lZAkJYnJzX3JlY2VpdmVkOjEsIGRtYV9kb25lOjE7Cgl1bnNpZ25lZAkJZG1hX2lzX3JlYWQ6MTsKCXVuc2lnbmVkCQlkbWFfaW5fdXNlOjE7CglpbnQJCQlkbWFfY2g7CglzcGlubG9ja190CQlkbWFfbG9jazsKCXN0cnVjdCB0aW1lcl9saXN0CWRtYV90aW1lcjsKCXVuc2lnbmVkCQlkbWFfbGVuOwoKCXNob3J0CQkJcG93ZXJfcGluOwoJc2hvcnQJCQl3cF9waW47CgoJaW50CQkJc3dpdGNoX3BpbjsKCXN0cnVjdCB3b3JrX3N0cnVjdAlzd2l0Y2hfd29yazsKCXN0cnVjdCB0aW1lcl9saXN0CXN3aXRjaF90aW1lcjsKCWludAkJCXN3aXRjaF9sYXN0X3N0YXRlOwp9OwoKc3RhdGljIGlubGluZSBpbnQKbW1jX29tYXBfY292ZXJfaXNfb3BlbihzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCkKewoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPCAwKQoJCXJldHVybiAwOwoJcmV0dXJuIG9tYXBfZ2V0X2dwaW9fZGF0YWluKGhvc3QtPnN3aXRjaF9waW4pOwp9CgpzdGF0aWMgc3NpemVfdAptbWNfb21hcF9zaG93X2NvdmVyX3N3aXRjaChzdHJ1Y3QgZGV2aWNlICpkZXYsCglzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpID8gIm9wZW4iIDoKCQkJImNsb3NlZCIpOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoY292ZXJfc3dpdGNoLCBTX0lSVUdPLCBtbWNfb21hcF9zaG93X2NvdmVyX3N3aXRjaCwgTlVMTCk7CgpzdGF0aWMgc3NpemVfdAptbWNfb21hcF9zaG93X2VuYWJsZV9wb2xsKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCBtbWNfb21hcF9lbmFibGVfcG9sbCk7Cn0KCnN0YXRpYyBzc2l6ZV90Cm1tY19vbWFwX3N0b3JlX2VuYWJsZV9wb2xsKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjb25zdCBjaGFyICpidWYsCglzaXplX3Qgc2l6ZSkKewoJaW50IGVuYWJsZV9wb2xsOwoKCWlmIChzc2NhbmYoYnVmLCAiJTEwZCIsICZlbmFibGVfcG9sbCkgIT0gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoZW5hYmxlX3BvbGwgIT0gbW1jX29tYXBfZW5hYmxlX3BvbGwpIHsKCQlzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCQltbWNfb21hcF9lbmFibGVfcG9sbCA9IGVuYWJsZV9wb2xsOwoJCWlmIChlbmFibGVfcG9sbCAmJiBob3N0LT5zd2l0Y2hfcGluID49IDApCgkJCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKCX0KCXJldHVybiBzaXplOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoZW5hYmxlX3BvbGwsIDA2NjQsCgkJICAgbW1jX29tYXBfc2hvd19lbmFibGVfcG9sbCwgbW1jX29tYXBfc3RvcmVfZW5hYmxlX3BvbGwpOwoKc3RhdGljIHZvaWQKbW1jX29tYXBfc3RhcnRfY29tbWFuZChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19jb21tYW5kICpjbWQpCnsKCXUzMiBjbWRyZWc7Cgl1MzIgcmVzcHR5cGU7Cgl1MzIgY21kdHlwZTsKCglob3N0LT5jbWQgPSBjbWQ7CgoJcmVzcHR5cGUgPSAwOwoJY21kdHlwZSA9IDA7CgoJLyogT3VyIGhhcmR3YXJlIG5lZWRzIHRvIGtub3cgZXhhY3QgdHlwZSAqLwoJc3dpdGNoIChtbWNfcmVzcF90eXBlKGNtZCkpIHsKCWNhc2UgTU1DX1JTUF9OT05FOgoJCWJyZWFrOwoJY2FzZSBNTUNfUlNQX1IxOgoJY2FzZSBNTUNfUlNQX1IxQjoKCQkvKiByZXNwIDEsIDFiLCA2LCA3ICovCgkJcmVzcHR5cGUgPSAxOwoJCWJyZWFrOwoJY2FzZSBNTUNfUlNQX1IyOgoJCXJlc3B0eXBlID0gMjsKCQlicmVhazsKCWNhc2UgTU1DX1JTUF9SMzoKCQlyZXNwdHlwZSA9IDM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLCAiSW52YWxpZCByZXNwb25zZSB0eXBlOiAlMDR4XG4iLCBtbWNfcmVzcF90eXBlKGNtZCkpOwoJCWJyZWFrOwoJfQoKCWlmIChtbWNfY21kX3R5cGUoY21kKSA9PSBNTUNfQ01EX0FEVEMpIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9BRFRDOwoJfSBlbHNlIGlmIChtbWNfY21kX3R5cGUoY21kKSA9PSBNTUNfQ01EX0JDKSB7CgkJY21kdHlwZSA9IE9NQVBfTU1DX0NNRFRZUEVfQkM7Cgl9IGVsc2UgaWYgKG1tY19jbWRfdHlwZShjbWQpID09IE1NQ19DTURfQkNSKSB7CgkJY21kdHlwZSA9IE9NQVBfTU1DX0NNRFRZUEVfQkNSOwoJfSBlbHNlIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9BQzsKCX0KCgljbWRyZWcgPSBjbWQtPm9wY29kZSB8IChyZXNwdHlwZSA8PCA4KSB8IChjbWR0eXBlIDw8IDEyKTsKCglpZiAoaG9zdC0+YnVzX21vZGUgPT0gTU1DX0JVU01PREVfT1BFTkRSQUlOKQoJCWNtZHJlZyB8PSAxIDw8IDY7CgoJaWYgKGNtZC0+ZmxhZ3MgJiBNTUNfUlNQX0JVU1kpCgkJY21kcmVnIHw9IDEgPDwgMTE7CgoJaWYgKGhvc3QtPmRhdGEgJiYgIShob3N0LT5kYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKSkKCQljbWRyZWcgfD0gMSA8PCAxNTsKCgljbGtfZW5hYmxlKGhvc3QtPmZjbGspOwoKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIENUTywgMjAwKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEFSR0wsIGNtZC0+YXJnICYgMHhmZmZmKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEFSR0gsIGNtZC0+YXJnID4+IDE2KTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIElFLAoJCSAgICAgICBPTUFQX01NQ19TVEFUX0FfRU1QVFkgICAgfCBPTUFQX01NQ19TVEFUX0FfRlVMTCAgICB8CgkJICAgICAgIE9NQVBfTU1DX1NUQVRfQ01EX0NSQyAgICB8IE9NQVBfTU1DX1NUQVRfQ01EX1RPVVQgIHwKCQkgICAgICAgT01BUF9NTUNfU1RBVF9EQVRBX0NSQyAgIHwgT01BUF9NTUNfU1RBVF9EQVRBX1RPVVQgfAoJCSAgICAgICBPTUFQX01NQ19TVEFUX0VORF9PRl9DTUQgfCBPTUFQX01NQ19TVEFUX0NBUkRfRVJSICB8CgkJICAgICAgIE9NQVBfTU1DX1NUQVRfRU5EX09GX0RBVEEpOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQ01ELCBjbWRyZWcpOwp9CgpzdGF0aWMgdm9pZAptbWNfb21hcF94ZmVyX2RvbmUoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfZGF0YSAqZGF0YSkKewoJaWYgKGhvc3QtPmRtYV9pbl91c2UpIHsKCQllbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkbWFfZGF0YV9kaXI7CgoJCUJVR19PTihob3N0LT5kbWFfY2ggPCAwKTsKCQlpZiAoZGF0YS0+ZXJyb3IpCgkJCW9tYXBfc3RvcF9kbWEoaG9zdC0+ZG1hX2NoKTsKCQkvKiBSZWxlYXNlIERNQSBjaGFubmVsIGxhemlseSAqLwoJCW1vZF90aW1lcigmaG9zdC0+ZG1hX3RpbWVyLCBqaWZmaWVzICsgSFopOwoJCWlmIChkYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKQoJCQlkbWFfZGF0YV9kaXIgPSBETUFfVE9fREVWSUNFOwoJCWVsc2UKCQkJZG1hX2RhdGFfZGlyID0gRE1BX0ZST01fREVWSUNFOwoJCWRtYV91bm1hcF9zZyhtbWNfZGV2KGhvc3QtPm1tYyksIGRhdGEtPnNnLCBob3N0LT5zZ19sZW4sCgkJCSAgICAgZG1hX2RhdGFfZGlyKTsKCX0KCWhvc3QtPmRhdGEgPSBOVUxMOwoJaG9zdC0+c2dfbGVuID0gMDsKCWNsa19kaXNhYmxlKGhvc3QtPmZjbGspOwoKCS8qIE5PVEU6ICBNTUMgbGF5ZXIgd2lsbCBzb21ldGltZXMgcG9sbC13YWl0IENNRDEzIG5leHQsIGlzc3VpbmcKCSAqIGRvemVucyBvZiByZXF1ZXN0cyB1bnRpbCB0aGUgY2FyZCBmaW5pc2hlcyB3cml0aW5nIGRhdGEuCgkgKiBJdCdkIGJlIGNoZWFwZXIgdG8ganVzdCB3YWl0IHRpbGwgYW4gRU9GQiBpbnRlcnJ1cHQgYXJyaXZlcy4uLgoJICovCgoJaWYgKCFkYXRhLT5zdG9wKSB7CgkJaG9zdC0+bXJxID0gTlVMTDsKCQltbWNfcmVxdWVzdF9kb25lKGhvc3QtPm1tYywgZGF0YS0+bXJxKTsKCQlyZXR1cm47Cgl9CgoJbW1jX29tYXBfc3RhcnRfY29tbWFuZChob3N0LCBkYXRhLT5zdG9wKTsKfQoKc3RhdGljIHZvaWQKbW1jX29tYXBfZW5kX29mX2RhdGEoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfZGF0YSAqZGF0YSkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBkb25lOwoKCWlmICghaG9zdC0+ZG1hX2luX3VzZSkgewoJCW1tY19vbWFwX3hmZXJfZG9uZShob3N0LCBkYXRhKTsKCQlyZXR1cm47Cgl9Cglkb25lID0gMDsKCXNwaW5fbG9ja19pcnFzYXZlKCZob3N0LT5kbWFfbG9jaywgZmxhZ3MpOwoJaWYgKGhvc3QtPmRtYV9kb25lKQoJCWRvbmUgPSAxOwoJZWxzZQoJCWhvc3QtPmJyc19yZWNlaXZlZCA9IDE7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZob3N0LT5kbWFfbG9jaywgZmxhZ3MpOwoJaWYgKGRvbmUpCgkJbW1jX29tYXBfeGZlcl9kb25lKGhvc3QsIGRhdGEpOwp9CgpzdGF0aWMgdm9pZAptbWNfb21hcF9kbWFfdGltZXIodW5zaWduZWQgbG9uZyBkYXRhKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKSBkYXRhOwoKCUJVR19PTihob3N0LT5kbWFfY2ggPCAwKTsKCW9tYXBfZnJlZV9kbWEoaG9zdC0+ZG1hX2NoKTsKCWhvc3QtPmRtYV9jaCA9IC0xOwp9CgpzdGF0aWMgdm9pZAptbWNfb21hcF9kbWFfZG9uZShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGRvbmU7CgoJZG9uZSA9IDA7CglzcGluX2xvY2tfaXJxc2F2ZSgmaG9zdC0+ZG1hX2xvY2ssIGZsYWdzKTsKCWlmIChob3N0LT5icnNfcmVjZWl2ZWQpCgkJZG9uZSA9IDE7CgllbHNlCgkJaG9zdC0+ZG1hX2RvbmUgPSAxOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaG9zdC0+ZG1hX2xvY2ssIGZsYWdzKTsKCWlmIChkb25lKQoJCW1tY19vbWFwX3hmZXJfZG9uZShob3N0LCBkYXRhKTsKfQoKc3RhdGljIHZvaWQKbW1jX29tYXBfY21kX2RvbmUoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfY29tbWFuZCAqY21kKQp7Cglob3N0LT5jbWQgPSBOVUxMOwoKCWlmIChjbWQtPmZsYWdzICYgTU1DX1JTUF9QUkVTRU5UKSB7CgkJaWYgKGNtZC0+ZmxhZ3MgJiBNTUNfUlNQXzEzNikgewoJCQkvKiByZXNwb25zZSB0eXBlIDIgKi8KCQkJY21kLT5yZXNwWzNdID0KCQkJCU9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQMCkgfAoJCQkJKE9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQMSkgPDwgMTYpOwoJCQljbWQtPnJlc3BbMl0gPQoJCQkJT01BUF9NTUNfUkVBRChob3N0LCBSU1AyKSB8CgkJCQkoT01BUF9NTUNfUkVBRChob3N0LCBSU1AzKSA8PCAxNik7CgkJCWNtZC0+cmVzcFsxXSA9CgkJCQlPTUFQX01NQ19SRUFEKGhvc3QsIFJTUDQpIHwKCQkJCShPTUFQX01NQ19SRUFEKGhvc3QsIFJTUDUpIDw8IDE2KTsKCQkJY21kLT5yZXNwWzBdID0KCQkJCU9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQNikgfAoJCQkJKE9NQVBfTU1DX1JFQUQoaG9zdCwgUlNQNykgPDwgMTYpOwoJCX0gZWxzZSB7CgkJCS8qIHJlc3BvbnNlIHR5cGVzIDEsIDFiLCAzLCA0LCA1LCA2ICovCgkJCWNtZC0+cmVzcFswXSA9CgkJCQlPTUFQX01NQ19SRUFEKGhvc3QsIFJTUDYpIHwKCQkJCShPTUFQX01NQ19SRUFEKGhvc3QsIFJTUDcpIDw8IDE2KTsKCQl9Cgl9CgoJaWYgKGhvc3QtPmRhdGEgPT0gTlVMTCB8fCBjbWQtPmVycm9yKSB7CgkJaG9zdC0+bXJxID0gTlVMTDsKCQljbGtfZGlzYWJsZShob3N0LT5mY2xrKTsKCQltbWNfcmVxdWVzdF9kb25lKGhvc3QtPm1tYywgY21kLT5tcnEpOwoJfQp9CgovKiBQSU8gb25seSAqLwpzdGF0aWMgdm9pZAptbWNfb21hcF9zZ190b19idWYoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QpCnsKCXN0cnVjdCBzY2F0dGVybGlzdCAqc2c7CgoJc2cgPSBob3N0LT5kYXRhLT5zZyArIGhvc3QtPnNnX2lkeDsKCWhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0ID0gc2ctPmxlbmd0aDsKCWhvc3QtPmJ1ZmZlciA9IHNnX3ZpcnQoc2cpOwoJaWYgKGhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0ID4gaG9zdC0+dG90YWxfYnl0ZXNfbGVmdCkKCQlob3N0LT5idWZmZXJfYnl0ZXNfbGVmdCA9IGhvc3QtPnRvdGFsX2J5dGVzX2xlZnQ7Cn0KCi8qIFBJTyBvbmx5ICovCnN0YXRpYyB2b2lkCm1tY19vbWFwX3hmZXJfZGF0YShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgaW50IHdyaXRlKQp7CglpbnQgbjsKCglpZiAoaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgPT0gMCkgewoJCWhvc3QtPnNnX2lkeCsrOwoJCUJVR19PTihob3N0LT5zZ19pZHggPT0gaG9zdC0+c2dfbGVuKTsKCQltbWNfb21hcF9zZ190b19idWYoaG9zdCk7Cgl9CgluID0gNjQ7CglpZiAobiA+IGhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0KQoJCW4gPSBob3N0LT5idWZmZXJfYnl0ZXNfbGVmdDsKCWhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0IC09IG47Cglob3N0LT50b3RhbF9ieXRlc19sZWZ0IC09IG47Cglob3N0LT5kYXRhLT5ieXRlc194ZmVyZWQgKz0gbjsKCglpZiAod3JpdGUpIHsKCQlfX3Jhd193cml0ZXN3KGhvc3QtPnZpcnRfYmFzZSArIE9NQVBfTU1DX1JFR19EQVRBLCBob3N0LT5idWZmZXIsIG4pOwoJfSBlbHNlIHsKCQlfX3Jhd19yZWFkc3coaG9zdC0+dmlydF9iYXNlICsgT01BUF9NTUNfUkVHX0RBVEEsIGhvc3QtPmJ1ZmZlciwgbik7Cgl9Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtbWNfb21hcF9yZXBvcnRfaXJxKHUxNiBzdGF0dXMpCnsKCXN0YXRpYyBjb25zdCBjaGFyICptbWNfb21hcF9zdGF0dXNfYml0c1tdID0gewoJCSJFT0MiLCAiQ0QiLCAiQ0IiLCAiQlJTIiwgIkVPRkIiLCAiRFRPIiwgIkRDUkMiLCAiQ1RPIiwKCQkiQ0NSQyIsICJDUlciLCAiQUYiLCAiQUUiLCAiT0NSQiIsICJDSVJRIiwgIkNFUlIiCgl9OwoJaW50IGksIGMgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKG1tY19vbWFwX3N0YXR1c19iaXRzKTsgaSsrKQoJCWlmIChzdGF0dXMgJiAoMSA8PCBpKSkgewoJCQlpZiAoYykKCQkJCXByaW50aygiICIpOwoJCQlwcmludGsoIiVzIiwgbW1jX29tYXBfc3RhdHVzX2JpdHNbaV0pOwoJCQljKys7CgkJfQp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbW1jX29tYXBfaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKiBob3N0ID0gKHN0cnVjdCBtbWNfb21hcF9ob3N0ICopZGV2X2lkOwoJdTE2IHN0YXR1czsKCWludCBlbmRfY29tbWFuZDsKCWludCBlbmRfdHJhbnNmZXI7CglpbnQgdHJhbnNmZXJfZXJyb3I7CgoJaWYgKGhvc3QtPmNtZCA9PSBOVUxMICYmIGhvc3QtPmRhdGEgPT0gTlVMTCkgewoJCXN0YXR1cyA9IE9NQVBfTU1DX1JFQUQoaG9zdCwgU1RBVCk7CgkJZGV2X2luZm8obW1jX2Rldihob3N0LT5tbWMpLCJzcHVyaW91cyBpcnEgMHglMDR4XG4iLCBzdGF0dXMpOwoJCWlmIChzdGF0dXMgIT0gMCkgewoJCQlPTUFQX01NQ19XUklURShob3N0LCBTVEFULCBzdGF0dXMpOwoJCQlPTUFQX01NQ19XUklURShob3N0LCBJRSwgMCk7CgkJfQoJCXJldHVybiBJUlFfSEFORExFRDsKCX0KCgllbmRfY29tbWFuZCA9IDA7CgllbmRfdHJhbnNmZXIgPSAwOwoJdHJhbnNmZXJfZXJyb3IgPSAwOwoKCXdoaWxlICgoc3RhdHVzID0gT01BUF9NTUNfUkVBRChob3N0LCBTVEFUKSkgIT0gMCkgewoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIFNUQVQsIHN0YXR1cyk7CiNpZmRlZiBDT05GSUdfTU1DX0RFQlVHCgkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJNTUMgSVJRICUwNHggKENNRCAlZCk6ICIsCgkJCXN0YXR1cywgaG9zdC0+Y21kICE9IE5VTEwgPyBob3N0LT5jbWQtPm9wY29kZSA6IC0xKTsKCQltbWNfb21hcF9yZXBvcnRfaXJxKHN0YXR1cyk7CgkJcHJpbnRrKCJcbiIpOwojZW5kaWYKCQlpZiAoaG9zdC0+dG90YWxfYnl0ZXNfbGVmdCkgewoJCQlpZiAoKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfQV9GVUxMKSB8fAoJCQkgICAgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfRU5EX09GX0RBVEEpKQoJCQkJbW1jX29tYXBfeGZlcl9kYXRhKGhvc3QsIDApOwoJCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9BX0VNUFRZKQoJCQkJbW1jX29tYXBfeGZlcl9kYXRhKGhvc3QsIDEpOwoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfRU5EX09GX0RBVEEpIHsKCQkJZW5kX3RyYW5zZmVyID0gMTsKCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0RBVEFfVE9VVCkgewoJCQlkZXZfZGJnKG1tY19kZXYoaG9zdC0+bW1jKSwgImRhdGEgdGltZW91dFxuIik7CgkJCWlmIChob3N0LT5kYXRhKSB7CgkJCQlob3N0LT5kYXRhLT5lcnJvciA9IC1FVElNRURPVVQ7CgkJCQl0cmFuc2Zlcl9lcnJvciA9IDE7CgkJCX0KCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0RBVEFfQ1JDKSB7CgkJCWlmIChob3N0LT5kYXRhKSB7CgkJCQlob3N0LT5kYXRhLT5lcnJvciA9IC1FSUxTRVE7CgkJCQlkZXZfZGJnKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJCQkgImRhdGEgQ1JDIGVycm9yLCBieXRlcyBsZWZ0ICVkXG4iLAoJCQkJCWhvc3QtPnRvdGFsX2J5dGVzX2xlZnQpOwoJCQkJdHJhbnNmZXJfZXJyb3IgPSAxOwoJCQl9IGVsc2UgewoJCQkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJkYXRhIENSQyBlcnJvclxuIik7CgkJCX0KCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0NNRF9UT1VUKSB7CgkJCS8qIFRpbWVvdXRzIGFyZSByb3V0aW5lIHdpdGggc29tZSBjb21tYW5kcyAqLwoJCQlpZiAoaG9zdC0+Y21kKSB7CgkJCQlpZiAoaG9zdC0+Y21kLT5vcGNvZGUgIT0gTU1DX0FMTF9TRU5EX0NJRCAmJgoJCQkJCQlob3N0LT5jbWQtPm9wY29kZSAhPQoJCQkJCQlNTUNfU0VORF9PUF9DT05EICYmCgkJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlICE9CgkJCQkJCU1NQ19BUFBfQ01EICYmCgkJCQkJCSFtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpKQoJCQkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJCQkiY29tbWFuZCB0aW1lb3V0LCBDTUQgJWRcbiIsCgkJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlKTsKCQkJCWhvc3QtPmNtZC0+ZXJyb3IgPSAtRVRJTUVET1VUOwoJCQkJZW5kX2NvbW1hbmQgPSAxOwoJCQl9CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9DTURfQ1JDKSB7CgkJCWlmIChob3N0LT5jbWQpIHsKCQkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJCSJjb21tYW5kIENSQyBlcnJvciAoQ01EJWQsIGFyZyAweCUwOHgpXG4iLAoJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlLCBob3N0LT5jbWQtPmFyZyk7CgkJCQlob3N0LT5jbWQtPmVycm9yID0gLUVJTFNFUTsKCQkJCWVuZF9jb21tYW5kID0gMTsKCQkJfSBlbHNlCgkJCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJCQkiY29tbWFuZCBDUkMgZXJyb3Igd2l0aG91dCBjbWQ/XG4iKTsKCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0NBUkRfRVJSKSB7CgkJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJImlnbm9yaW5nIGNhcmQgc3RhdHVzIGVycm9yIChDTUQlZClcbiIsCgkJCQlob3N0LT5jbWQtPm9wY29kZSk7CgkJCWVuZF9jb21tYW5kID0gMTsKCQl9CgoJCS8qCgkJICogTk9URTogT24gMTYxMCB0aGUgRU5EX09GX0NNRCBtYXkgY29tZSB0b28gZWFybHkgd2hlbgoJCSAqIHN0YXJ0aW5nIGEgd3JpdGUgCgkJICovCgkJaWYgKChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0VORF9PRl9DTUQpICYmCgkJICAgICghKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfQV9FTVBUWSkpKSB7CgkJCWVuZF9jb21tYW5kID0gMTsKCQl9Cgl9CgoJaWYgKGVuZF9jb21tYW5kKSB7CgkJbW1jX29tYXBfY21kX2RvbmUoaG9zdCwgaG9zdC0+Y21kKTsKCX0KCWlmICh0cmFuc2Zlcl9lcnJvcikKCQltbWNfb21hcF94ZmVyX2RvbmUoaG9zdCwgaG9zdC0+ZGF0YSk7CgllbHNlIGlmIChlbmRfdHJhbnNmZXIpCgkJbW1jX29tYXBfZW5kX29mX2RhdGEoaG9zdCwgaG9zdC0+ZGF0YSk7CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbW1jX29tYXBfc3dpdGNoX2lycShpbnQgaXJxLCB2b2lkICpkZXZfaWQpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gKHN0cnVjdCBtbWNfb21hcF9ob3N0ICopIGRldl9pZDsKCglzY2hlZHVsZV93b3JrKCZob3N0LT5zd2l0Y2hfd29yayk7CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgdm9pZCBtbWNfb21hcF9zd2l0Y2hfdGltZXIodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gKHN0cnVjdCBtbWNfb21hcF9ob3N0ICopIGFyZzsKCglzY2hlZHVsZV93b3JrKCZob3N0LT5zd2l0Y2hfd29yayk7Cn0KCnN0YXRpYyB2b2lkIG1tY19vbWFwX3N3aXRjaF9oYW5kbGVyKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBjb250YWluZXJfb2Yod29yaywgc3RydWN0IG1tY19vbWFwX2hvc3QsIHN3aXRjaF93b3JrKTsKCXN0cnVjdCBtbWNfY2FyZCAqY2FyZDsKCXN0YXRpYyBpbnQgY29tcGxhaW5lZCA9IDA7CglpbnQgY2FyZHMgPSAwLCBjb3Zlcl9vcGVuOwoKCWlmIChob3N0LT5zd2l0Y2hfcGluID09IC0xKQoJCXJldHVybjsKCWNvdmVyX29wZW4gPSBtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpOwoJaWYgKGNvdmVyX29wZW4gIT0gaG9zdC0+c3dpdGNoX2xhc3Rfc3RhdGUpIHsKCQlrb2JqZWN0X3VldmVudCgmaG9zdC0+ZGV2LT5rb2JqLCBLT0JKX0NIQU5HRSk7CgkJaG9zdC0+c3dpdGNoX2xhc3Rfc3RhdGUgPSBjb3Zlcl9vcGVuOwoJfQoJbW1jX2RldGVjdF9jaGFuZ2UoaG9zdC0+bW1jLCAwKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY2FyZCwgJmhvc3QtPm1tYy0+Y2FyZHMsIG5vZGUpIHsKCQlpZiAobW1jX2NhcmRfcHJlc2VudChjYXJkKSkKCQkJY2FyZHMrKzsKCX0KCWlmIChtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpKSB7CgkJaWYgKCFjb21wbGFpbmVkKSB7CgkJCWRldl9pbmZvKG1tY19kZXYoaG9zdC0+bW1jKSwgImNvdmVyIGlzIG9wZW5cbiIpOwoJCQljb21wbGFpbmVkID0gMTsKCQl9CgkJaWYgKG1tY19vbWFwX2VuYWJsZV9wb2xsKQoJCQltb2RfdGltZXIoJmhvc3QtPnN3aXRjaF90aW1lciwgamlmZmllcyArCgkJCQltc2Vjc190b19qaWZmaWVzKE9NQVBfTU1DX1NXSVRDSF9QT0xMX0RFTEFZKSk7Cgl9IGVsc2UgewoJCWNvbXBsYWluZWQgPSAwOwoJfQp9CgovKiBQcmVwYXJlIHRvIHRyYW5zZmVyIHRoZSBuZXh0IHNlZ21lbnQgb2YgYSBzY2F0dGVybGlzdCAqLwpzdGF0aWMgdm9pZAptbWNfb21hcF9wcmVwYXJlX2RtYShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7CglpbnQgZG1hX2NoID0gaG9zdC0+ZG1hX2NoOwoJdW5zaWduZWQgbG9uZyBkYXRhX2FkZHI7Cgl1MTYgYnVmLCBmcmFtZTsKCXUzMiBjb3VudDsKCXN0cnVjdCBzY2F0dGVybGlzdCAqc2cgPSAmZGF0YS0+c2dbaG9zdC0+c2dfaWR4XTsKCWludCBzcmNfcG9ydCA9IDA7CglpbnQgZHN0X3BvcnQgPSAwOwoJaW50IHN5bmNfZGV2ID0gMDsKCglkYXRhX2FkZHIgPSBob3N0LT5waHlzX2Jhc2UgKyBPTUFQX01NQ19SRUdfREFUQTsKCWZyYW1lID0gZGF0YS0+Ymxrc3o7Cgljb3VudCA9IHNnX2RtYV9sZW4oc2cpOwoKCWlmICgoZGF0YS0+YmxvY2tzID09IDEpICYmIChjb3VudCA+IGRhdGEtPmJsa3N6KSkKCQljb3VudCA9IGZyYW1lOwoKCWhvc3QtPmRtYV9sZW4gPSBjb3VudDsKCgkvKiBGSUZPIGlzIDE2eDIgYnl0ZXMgb24gMTV4eCwgYW5kIDMyeDIgYnl0ZXMgb24gMTZ4eCBhbmQgMjR4eC4KCSAqIFVzZSAxNiBvciAzMiB3b3JkIGZyYW1lcyB3aGVuIHRoZSBibG9ja3NpemUgaXMgYXQgbGVhc3QgdGhhdCBsYXJnZS4KCSAqIEJsb2Nrc2l6ZSBpcyB1c3VhbGx5IDUxMiBieXRlczsgYnV0IG5vdCBmb3Igc29tZSBTRCByZWFkcy4KCSAqLwoJaWYgKGNwdV9pc19vbWFwMTV4eCgpICYmIGZyYW1lID4gMzIpCgkJZnJhbWUgPSAzMjsKCWVsc2UgaWYgKGZyYW1lID4gNjQpCgkJZnJhbWUgPSA2NDsKCWNvdW50IC89IGZyYW1lOwoJZnJhbWUgPj49IDE7CgoJaWYgKCEoZGF0YS0+ZmxhZ3MgJiBNTUNfREFUQV9XUklURSkpIHsKCQlidWYgPSAweDgwMGYgfCAoKGZyYW1lIC0gMSkgPDwgOCk7CgoJCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCQlzcmNfcG9ydCA9IE9NQVBfRE1BX1BPUlRfVElQQjsKCQkJZHN0X3BvcnQgPSBPTUFQX0RNQV9QT1JUX0VNSUZGOwoJCX0KCQlpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJCXN5bmNfZGV2ID0gT01BUDI0WFhfRE1BX01NQzFfUlg7CgoJCW9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKGRtYV9jaCwgc3JjX3BvcnQsCgkJCQkJT01BUF9ETUFfQU1PREVfQ09OU1RBTlQsCgkJCQkJZGF0YV9hZGRyLCAwLCAwKTsKCQlvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMoZG1hX2NoLCBkc3RfcG9ydCwKCQkJCQkgT01BUF9ETUFfQU1PREVfUE9TVF9JTkMsCgkJCQkJIHNnX2RtYV9hZGRyZXNzKHNnKSwgMCwgMCk7CgkJb21hcF9zZXRfZG1hX2Rlc3RfZGF0YV9wYWNrKGRtYV9jaCwgMSk7CgkJb21hcF9zZXRfZG1hX2Rlc3RfYnVyc3RfbW9kZShkbWFfY2gsIE9NQVBfRE1BX0RBVEFfQlVSU1RfNCk7Cgl9IGVsc2UgewoJCWJ1ZiA9IDB4MGY4MCB8ICgoZnJhbWUgLSAxKSA8PCAwKTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCXNyY19wb3J0ID0gT01BUF9ETUFfUE9SVF9FTUlGRjsKCQkJZHN0X3BvcnQgPSBPTUFQX0RNQV9QT1JUX1RJUEI7CgkJfQoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQkJc3luY19kZXYgPSBPTUFQMjRYWF9ETUFfTU1DMV9UWDsKCgkJb21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKGRtYV9jaCwgZHN0X3BvcnQsCgkJCQkJIE9NQVBfRE1BX0FNT0RFX0NPTlNUQU5ULAoJCQkJCSBkYXRhX2FkZHIsIDAsIDApOwoJCW9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKGRtYV9jaCwgc3JjX3BvcnQsCgkJCQkJT01BUF9ETUFfQU1PREVfUE9TVF9JTkMsCgkJCQkJc2dfZG1hX2FkZHJlc3Moc2cpLCAwLCAwKTsKCQlvbWFwX3NldF9kbWFfc3JjX2RhdGFfcGFjayhkbWFfY2gsIDEpOwoJCW9tYXBfc2V0X2RtYV9zcmNfYnVyc3RfbW9kZShkbWFfY2gsIE9NQVBfRE1BX0RBVEFfQlVSU1RfNCk7Cgl9CgoJLyogTWF4IGxpbWl0IGZvciBETUEgZnJhbWUgY291bnQgaXMgMHhmZmZmICovCglCVUdfT04oY291bnQgPiAweGZmZmYpOwoKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEJVRiwgYnVmKTsKCW9tYXBfc2V0X2RtYV90cmFuc2Zlcl9wYXJhbXMoZG1hX2NoLCBPTUFQX0RNQV9EQVRBX1RZUEVfUzE2LAoJCQkJICAgICBmcmFtZSwgY291bnQsIE9NQVBfRE1BX1NZTkNfRlJBTUUsCgkJCQkgICAgIHN5bmNfZGV2LCAwKTsKfQoKLyogQSBzY2F0dGVybGlzdCBzZWdtZW50IGNvbXBsZXRlZCAqLwpzdGF0aWMgdm9pZCBtbWNfb21hcF9kbWFfY2IoaW50IGxjaCwgdTE2IGNoX3N0YXR1cywgdm9pZCAqZGF0YSkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgZGF0YTsKCXN0cnVjdCBtbWNfZGF0YSAqbW1jZGF0ID0gaG9zdC0+ZGF0YTsKCglpZiAodW5saWtlbHkoaG9zdC0+ZG1hX2NoIDwgMCkpIHsKCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJIkRNQSBjYWxsYmFjayB3aGlsZSBETUEgbm90IGVuYWJsZWRcbiIpOwoJCXJldHVybjsKCX0KCS8qIEZJWE1FOiBXZSByZWFsbHkgc2hvdWxkIGRvIHNvbWV0aGluZyB0byBfaGFuZGxlXyB0aGUgZXJyb3JzICovCglpZiAoY2hfc3RhdHVzICYgT01BUDFfRE1BX1RPVVRfSVJRKSB7CgkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksIkRNQSB0aW1lb3V0XG4iKTsKCQlyZXR1cm47Cgl9CglpZiAoY2hfc3RhdHVzICYgT01BUF9ETUFfRFJPUF9JUlEpIHsKCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwgIkRNQSBzeW5jIGVycm9yXG4iKTsKCQlyZXR1cm47Cgl9CglpZiAoIShjaF9zdGF0dXMgJiBPTUFQX0RNQV9CTE9DS19JUlEpKSB7CgkJcmV0dXJuOwoJfQoJbW1jZGF0LT5ieXRlc194ZmVyZWQgKz0gaG9zdC0+ZG1hX2xlbjsKCWhvc3QtPnNnX2lkeCsrOwoJaWYgKGhvc3QtPnNnX2lkeCA8IGhvc3QtPnNnX2xlbikgewoJCW1tY19vbWFwX3ByZXBhcmVfZG1hKGhvc3QsIGhvc3QtPmRhdGEpOwoJCW9tYXBfc3RhcnRfZG1hKGhvc3QtPmRtYV9jaCk7Cgl9IGVsc2UKCQltbWNfb21hcF9kbWFfZG9uZShob3N0LCBob3N0LT5kYXRhKTsKfQoKc3RhdGljIGludCBtbWNfb21hcF9nZXRfZG1hX2NoYW5uZWwoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfZGF0YSAqZGF0YSkKewoJY29uc3QgY2hhciAqZGV2X25hbWU7CglpbnQgc3luY19kZXYsIGRtYV9jaCwgaXNfcmVhZCwgcjsKCglpc19yZWFkID0gIShkYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKTsKCWRlbF90aW1lcl9zeW5jKCZob3N0LT5kbWFfdGltZXIpOwoJaWYgKGhvc3QtPmRtYV9jaCA+PSAwKSB7CgkJaWYgKGlzX3JlYWQgPT0gaG9zdC0+ZG1hX2lzX3JlYWQpCgkJCXJldHVybiAwOwoJCW9tYXBfZnJlZV9kbWEoaG9zdC0+ZG1hX2NoKTsKCQlob3N0LT5kbWFfY2ggPSAtMTsKCX0KCglpZiAoaXNfcmVhZCkgewoJCWlmIChob3N0LT5pZCA9PSAxKSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DX1JYOwoJCQlkZXZfbmFtZSA9ICJNTUMxIHJlYWQiOwoJCX0gZWxzZSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DMl9SWDsKCQkJZGV2X25hbWUgPSAiTU1DMiByZWFkIjsKCQl9Cgl9IGVsc2UgewoJCWlmIChob3N0LT5pZCA9PSAxKSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DX1RYOwoJCQlkZXZfbmFtZSA9ICJNTUMxIHdyaXRlIjsKCQl9IGVsc2UgewoJCQlzeW5jX2RldiA9IE9NQVBfRE1BX01NQzJfVFg7CgkJCWRldl9uYW1lID0gIk1NQzIgd3JpdGUiOwoJCX0KCX0KCXIgPSBvbWFwX3JlcXVlc3RfZG1hKHN5bmNfZGV2LCBkZXZfbmFtZSwgbW1jX29tYXBfZG1hX2NiLAoJCQkgICAgIGhvc3QsICZkbWFfY2gpOwoJaWYgKHIgIT0gMCkgewoJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAib21hcF9yZXF1ZXN0X2RtYSgpIGZhaWxlZCB3aXRoICVkXG4iLCByKTsKCQlyZXR1cm4gcjsKCX0KCWhvc3QtPmRtYV9jaCA9IGRtYV9jaDsKCWhvc3QtPmRtYV9pc19yZWFkID0gaXNfcmVhZDsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9jbWRfdGltZW91dChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCXUxNiByZWc7CgoJcmVnID0gT01BUF9NTUNfUkVBRChob3N0LCBTRElPKTsKCXJlZyAmPSB+KDEgPDwgNSk7CglPTUFQX01NQ19XUklURShob3N0LCBTRElPLCByZWcpOwoJLyogU2V0IG1heGltdW0gdGltZW91dCAqLwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgQ1RPLCAweGZmKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9kYXRhX3RpbWVvdXQoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfcmVxdWVzdCAqcmVxKQp7CglpbnQgdGltZW91dDsKCXUxNiByZWc7CgoJLyogQ29udmVydCBucyB0byBjbG9jayBjeWNsZXMgYnkgYXNzdW1pbmcgMjBNSHogZnJlcXVlbmN5CgkgKiAxIGN5Y2xlIGF0IDIwTUh6ID0gNTAwIG5zCgkgKi8KCXRpbWVvdXQgPSByZXEtPmRhdGEtPnRpbWVvdXRfY2xrcyArIHJlcS0+ZGF0YS0+dGltZW91dF9ucyAvIDUwMDsKCgkvKiBDaGVjayBpZiB3ZSBuZWVkIHRvIHVzZSB0aW1lb3V0IG11bHRpcGxpZXIgcmVnaXN0ZXIgKi8KCXJlZyA9IE9NQVBfTU1DX1JFQUQoaG9zdCwgU0RJTyk7CglpZiAodGltZW91dCA+IDB4ZmZmZikgewoJCXJlZyB8PSAoMSA8PCA1KTsKCQl0aW1lb3V0IC89IDEwMjQ7Cgl9IGVsc2UKCQlyZWcgJj0gfigxIDw8IDUpOwoJT01BUF9NTUNfV1JJVEUoaG9zdCwgU0RJTywgcmVnKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIERUTywgdGltZW91dCk7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX3ByZXBhcmVfZGF0YShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCXN0cnVjdCBtbWNfZGF0YSAqZGF0YSA9IHJlcS0+ZGF0YTsKCWludCBpLCB1c2VfZG1hLCBibG9ja19zaXplOwoJdW5zaWduZWQgc2dfbGVuOwoKCWhvc3QtPmRhdGEgPSBkYXRhOwoJaWYgKGRhdGEgPT0gTlVMTCkgewoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEJMRU4sIDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIE5CTEssIDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEJVRiwgMCk7CgkJaG9zdC0+ZG1hX2luX3VzZSA9IDA7CgkJc2V0X2NtZF90aW1lb3V0KGhvc3QsIHJlcSk7CgkJcmV0dXJuOwoJfQoKCWJsb2NrX3NpemUgPSBkYXRhLT5ibGtzejsKCglPTUFQX01NQ19XUklURShob3N0LCBOQkxLLCBkYXRhLT5ibG9ja3MgLSAxKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEJMRU4sIGJsb2NrX3NpemUgLSAxKTsKCXNldF9kYXRhX3RpbWVvdXQoaG9zdCwgcmVxKTsKCgkvKiBjb3BlIHdpdGggY2FsbGluZyBsYXllciBjb25mdXNpb247IGl0IGlzc3VlcyAic2luZ2xlCgkgKiBibG9jayIgd3JpdGVzIHVzaW5nIG11bHRpLWJsb2NrIHNjYXR0ZXJsaXN0cy4KCSAqLwoJc2dfbGVuID0gKGRhdGEtPmJsb2NrcyA9PSAxKSA/IDEgOiBkYXRhLT5zZ19sZW47CgoJLyogT25seSBkbyBETUEgZm9yIGVudGlyZSBibG9ja3MgKi8KCXVzZV9kbWEgPSBob3N0LT51c2VfZG1hOwoJaWYgKHVzZV9kbWEpIHsKCQlmb3IgKGkgPSAwOyBpIDwgc2dfbGVuOyBpKyspIHsKCQkJaWYgKChkYXRhLT5zZ1tpXS5sZW5ndGggJSBibG9ja19zaXplKSAhPSAwKSB7CgkJCQl1c2VfZG1hID0gMDsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJfQoKCWhvc3QtPnNnX2lkeCA9IDA7CglpZiAodXNlX2RtYSkgewoJCWlmIChtbWNfb21hcF9nZXRfZG1hX2NoYW5uZWwoaG9zdCwgZGF0YSkgPT0gMCkgewoJCQllbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkbWFfZGF0YV9kaXI7CgoJCQlpZiAoZGF0YS0+ZmxhZ3MgJiBNTUNfREFUQV9XUklURSkKCQkJCWRtYV9kYXRhX2RpciA9IERNQV9UT19ERVZJQ0U7CgkJCWVsc2UKCQkJCWRtYV9kYXRhX2RpciA9IERNQV9GUk9NX0RFVklDRTsKCgkJCWhvc3QtPnNnX2xlbiA9IGRtYV9tYXBfc2cobW1jX2Rldihob3N0LT5tbWMpLCBkYXRhLT5zZywKCQkJCQkJc2dfbGVuLCBkbWFfZGF0YV9kaXIpOwoJCQlob3N0LT50b3RhbF9ieXRlc19sZWZ0ID0gMDsKCQkJbW1jX29tYXBfcHJlcGFyZV9kbWEoaG9zdCwgcmVxLT5kYXRhKTsKCQkJaG9zdC0+YnJzX3JlY2VpdmVkID0gMDsKCQkJaG9zdC0+ZG1hX2RvbmUgPSAwOwoJCQlob3N0LT5kbWFfaW5fdXNlID0gMTsKCQl9IGVsc2UKCQkJdXNlX2RtYSA9IDA7Cgl9CgoJLyogUmV2ZXJ0IHRvIFBJTz8gKi8KCWlmICghdXNlX2RtYSkgewoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIEJVRiwgMHgxZjFmKTsKCQlob3N0LT50b3RhbF9ieXRlc19sZWZ0ID0gZGF0YS0+YmxvY2tzICogYmxvY2tfc2l6ZTsKCQlob3N0LT5zZ19sZW4gPSBzZ19sZW47CgkJbW1jX29tYXBfc2dfdG9fYnVmKGhvc3QpOwoJCWhvc3QtPmRtYV9pbl91c2UgPSAwOwoJfQp9CgpzdGF0aWMgdm9pZCBtbWNfb21hcF9yZXF1ZXN0KHN0cnVjdCBtbWNfaG9zdCAqbW1jLCBzdHJ1Y3QgbW1jX3JlcXVlc3QgKnJlcSkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBtbWNfcHJpdihtbWMpOwoKCVdBUk5fT04oaG9zdC0+bXJxICE9IE5VTEwpOwoKCWhvc3QtPm1ycSA9IHJlcTsKCgkvKiBvbmx5IHRvdWNoIGZpZm8gQUZURVIgdGhlIGNvbnRyb2xsZXIgcmVhZGllcyBpdCAqLwoJbW1jX29tYXBfcHJlcGFyZV9kYXRhKGhvc3QsIHJlcSk7CgltbWNfb21hcF9zdGFydF9jb21tYW5kKGhvc3QsIHJlcS0+Y21kKTsKCWlmIChob3N0LT5kbWFfaW5fdXNlKQoJCW9tYXBfc3RhcnRfZG1hKGhvc3QtPmRtYV9jaCk7Cn0KCnN0YXRpYyB2b2lkIGlubm92YXRvcl9mcGdhX3NvY2tldF9wb3dlcihpbnQgb24pCnsKI2lmIGRlZmluZWQoQ09ORklHX01BQ0hfT01BUF9JTk5PVkFUT1IpICYmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDE1WFgpCglpZiAob24pIHsKCQlmcGdhX3dyaXRlKGZwZ2FfcmVhZChPTUFQMTUxMF9GUEdBX1BPV0VSKSB8ICgxIDw8IDMpLAoJCSAgICAgT01BUDE1MTBfRlBHQV9QT1dFUik7Cgl9IGVsc2UgewoJCWZwZ2Ffd3JpdGUoZnBnYV9yZWFkKE9NQVAxNTEwX0ZQR0FfUE9XRVIpICYgfigxIDw8IDMpLAoJCSAgICAgT01BUDE1MTBfRlBHQV9QT1dFUik7Cgl9CiNlbmRpZgp9CgovKgogKiBUdXJuIHRoZSBzb2NrZXQgcG93ZXIgb24vb2ZmLiBJbm5vdmF0b3IgdXNlcyBGUEdBLCBtb3N0IGJvYXJkcwogKiBwcm9iYWJseSB1c2UgR1BJTy4KICovCnN0YXRpYyB2b2lkIG1tY19vbWFwX3Bvd2VyKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBpbnQgb24pCnsKCWlmIChvbikgewoJCWlmIChtYWNoaW5lX2lzX29tYXBfaW5ub3ZhdG9yKCkpCgkJCWlubm92YXRvcl9mcGdhX3NvY2tldF9wb3dlcigxKTsKCQllbHNlIGlmIChtYWNoaW5lX2lzX29tYXBfaDIoKSkKCQkJdHBzNjUwMTBfc2V0X2dwaW9fb3V0X3ZhbHVlKEdQSU8zLCBISUdIKTsKCQllbHNlIGlmIChtYWNoaW5lX2lzX29tYXBfaDMoKSkKCQkJLyogR1BJTyA0IG9mIFRQUzY1MDEwIHNlbmRzIFNEX0VOIHNpZ25hbCAqLwoJCQl0cHM2NTAxMF9zZXRfZ3Bpb19vdXRfdmFsdWUoR1BJTzQsIEhJR0gpOwoJCWVsc2UgaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJCXUxNiByZWcgPSBPTUFQX01NQ19SRUFEKGhvc3QsIENPTik7CgkJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIENPTiwgcmVnIHwgKDEgPDwgMTEpKTsKCQl9IGVsc2UKCQkJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKQoJCQkJb21hcF9zZXRfZ3Bpb19kYXRhb3V0KGhvc3QtPnBvd2VyX3BpbiwgMSk7Cgl9IGVsc2UgewoJCWlmIChtYWNoaW5lX2lzX29tYXBfaW5ub3ZhdG9yKCkpCgkJCWlubm92YXRvcl9mcGdhX3NvY2tldF9wb3dlcigwKTsKCQllbHNlIGlmIChtYWNoaW5lX2lzX29tYXBfaDIoKSkKCQkJdHBzNjUwMTBfc2V0X2dwaW9fb3V0X3ZhbHVlKEdQSU8zLCBMT1cpOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMygpKQoJCQl0cHM2NTAxMF9zZXRfZ3Bpb19vdXRfdmFsdWUoR1BJTzQsIExPVyk7CgkJZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkJdTE2IHJlZyA9IE9NQVBfTU1DX1JFQUQoaG9zdCwgQ09OKTsKCQkJT01BUF9NTUNfV1JJVEUoaG9zdCwgQ09OLCByZWcgJiB+KDEgPDwgMTEpKTsKCQl9IGVsc2UKCQkJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKQoJCQkJb21hcF9zZXRfZ3Bpb19kYXRhb3V0KGhvc3QtPnBvd2VyX3BpbiwgMCk7Cgl9Cn0KCnN0YXRpYyBpbnQgbW1jX29tYXBfY2FsY19kaXZpc29yKHN0cnVjdCBtbWNfaG9zdCAqbW1jLCBzdHJ1Y3QgbW1jX2lvcyAqaW9zKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IG1tY19wcml2KG1tYyk7CglpbnQgZnVuY19jbGtfcmF0ZSA9IGNsa19nZXRfcmF0ZShob3N0LT5mY2xrKTsKCWludCBkc29yOwoKCWlmIChpb3MtPmNsb2NrID09IDApCgkJcmV0dXJuIDA7CgoJZHNvciA9IGZ1bmNfY2xrX3JhdGUgLyBpb3MtPmNsb2NrOwoJaWYgKGRzb3IgPCAxKQoJCWRzb3IgPSAxOwoKCWlmIChmdW5jX2Nsa19yYXRlIC8gZHNvciA+IGlvcy0+Y2xvY2spCgkJZHNvcisrOwoKCWlmIChkc29yID4gMjUwKQoJCWRzb3IgPSAyNTA7Cglkc29yKys7CgoJaWYgKGlvcy0+YnVzX3dpZHRoID09IE1NQ19CVVNfV0lEVEhfNCkKCQlkc29yIHw9IDEgPDwgMTU7CgoJcmV0dXJuIGRzb3I7Cn0KCnN0YXRpYyB2b2lkIG1tY19vbWFwX3NldF9pb3Moc3RydWN0IG1tY19ob3N0ICptbWMsIHN0cnVjdCBtbWNfaW9zICppb3MpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gbW1jX3ByaXYobW1jKTsKCWludCBkc29yOwoJaW50IGk7CgoJZHNvciA9IG1tY19vbWFwX2NhbGNfZGl2aXNvcihtbWMsIGlvcyk7Cglob3N0LT5idXNfbW9kZSA9IGlvcy0+YnVzX21vZGU7Cglob3N0LT5od19idXNfbW9kZSA9IGhvc3QtPmJ1c19tb2RlOwoKCXN3aXRjaCAoaW9zLT5wb3dlcl9tb2RlKSB7CgljYXNlIE1NQ19QT1dFUl9PRkY6CgkJbW1jX29tYXBfcG93ZXIoaG9zdCwgMCk7CgkJYnJlYWs7CgljYXNlIE1NQ19QT1dFUl9VUDoKCQkvKiBDYW5ub3QgdG91Y2ggZHNvciB5ZXQsIGp1c3QgcG93ZXIgdXAgTU1DICovCgkJbW1jX29tYXBfcG93ZXIoaG9zdCwgMSk7CgkJcmV0dXJuOwoJY2FzZSBNTUNfUE9XRVJfT046CgkJZHNvciB8PSAxIDw8IDExOwoJCWJyZWFrOwoJfQoKCWNsa19lbmFibGUoaG9zdC0+ZmNsayk7CgoJLyogT24gaW5zYW5lbHkgaGlnaCBhcm1fcGVyIGZyZXF1ZW5jaWVzIHNvbWV0aGluZyBzb21ldGltZXMKCSAqIGdvZXMgc29tZWhvdyBvdXQgb2Ygc3luYywgYW5kIHRoZSBQT1cgYml0IGlzIG5vdCBiZWluZyBzZXQsCgkgKiB3aGljaCByZXN1bHRzIGluIHRoZSB3aGlsZSBsb29wIGJlbG93IGdldHRpbmcgc3R1Y2suCgkgKiBXcml0aW5nIHRvIHRoZSBDT04gcmVnaXN0ZXIgdHdpY2Ugc2VlbXMgdG8gZG8gdGhlIHRyaWNrLiAqLwoJZm9yIChpID0gMDsgaSA8IDI7IGkrKykKCQlPTUFQX01NQ19XUklURShob3N0LCBDT04sIGRzb3IpOwoJaWYgKGlvcy0+cG93ZXJfbW9kZSA9PSBNTUNfUE9XRVJfT04pIHsKCQkvKiBTZW5kIGNsb2NrIGN5Y2xlcywgcG9sbCBjb21wbGV0aW9uICovCgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgSUUsIDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIFNUQVQsIDB4ZmZmZik7CgkJT01BUF9NTUNfV1JJVEUoaG9zdCwgQ01ELCAxIDw8IDcpOwoJCXdoaWxlICgoT01BUF9NTUNfUkVBRChob3N0LCBTVEFUKSAmIDEpID09IDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QsIFNUQVQsIDEpOwoJfQoJY2xrX2Rpc2FibGUoaG9zdC0+ZmNsayk7Cn0KCnN0YXRpYyBpbnQgbW1jX29tYXBfZ2V0X3JvKHN0cnVjdCBtbWNfaG9zdCAqbW1jKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IG1tY19wcml2KG1tYyk7CgoJcmV0dXJuIGhvc3QtPndwX3BpbiAmJiBvbWFwX2dldF9ncGlvX2RhdGFpbihob3N0LT53cF9waW4pOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IG1tY19ob3N0X29wcyBtbWNfb21hcF9vcHMgPSB7CgkucmVxdWVzdAk9IG1tY19vbWFwX3JlcXVlc3QsCgkuc2V0X2lvcwk9IG1tY19vbWFwX3NldF9pb3MsCgkuZ2V0X3JvCQk9IG1tY19vbWFwX2dldF9ybywKfTsKCnN0YXRpYyBpbnQgX19pbml0IG1tY19vbWFwX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBvbWFwX21tY19jb25mICptaW5mbyA9IHBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwoJc3RydWN0IG1tY19ob3N0ICptbWM7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IE5VTEw7CglzdHJ1Y3QgcmVzb3VyY2UgKnJlczsKCWludCByZXQgPSAwOwoJaW50IGlycTsKCglpZiAobWluZm8gPT0gTlVMTCkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgInBsYXRmb3JtIGRhdGEgbWlzc2luZ1xuIik7CgkJcmV0dXJuIC1FTlhJTzsKCX0KCglyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwoJaXJxID0gcGxhdGZvcm1fZ2V0X2lycShwZGV2LCAwKTsKCWlmIChyZXMgPT0gTlVMTCB8fCBpcnEgPCAwKQoJCXJldHVybiAtRU5YSU87CgoJcmVzID0gcmVxdWVzdF9tZW1fcmVnaW9uKHJlcy0+c3RhcnQsIHJlcy0+ZW5kIC0gcmVzLT5zdGFydCArIDEsCgkJCSAgICAgICAgIHBkZXYtPm5hbWUpOwoJaWYgKHJlcyA9PSBOVUxMKQoJCXJldHVybiAtRUJVU1k7CgoJbW1jID0gbW1jX2FsbG9jX2hvc3Qoc2l6ZW9mKHN0cnVjdCBtbWNfb21hcF9ob3N0KSwgJnBkZXYtPmRldik7CglpZiAobW1jID09IE5VTEwpIHsKCQlyZXQgPSAtRU5PTUVNOwoJCWdvdG8gZXJyX2ZyZWVfbWVtX3JlZ2lvbjsKCX0KCglob3N0ID0gbW1jX3ByaXYobW1jKTsKCWhvc3QtPm1tYyA9IG1tYzsKCglzcGluX2xvY2tfaW5pdCgmaG9zdC0+ZG1hX2xvY2spOwoJaW5pdF90aW1lcigmaG9zdC0+ZG1hX3RpbWVyKTsKCWhvc3QtPmRtYV90aW1lci5mdW5jdGlvbiA9IG1tY19vbWFwX2RtYV90aW1lcjsKCWhvc3QtPmRtYV90aW1lci5kYXRhID0gKHVuc2lnbmVkIGxvbmcpIGhvc3Q7CgoJaG9zdC0+aWQgPSBwZGV2LT5pZDsKCWhvc3QtPm1lbV9yZXMgPSByZXM7Cglob3N0LT5pcnEgPSBpcnE7CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJaG9zdC0+aWNsayA9IGNsa19nZXQoJnBkZXYtPmRldiwgIm1tY19pY2siKTsKCQlpZiAoSVNfRVJSKGhvc3QtPmljbGspKQoJCQlnb3RvIGVycl9mcmVlX21tY19ob3N0OwoJCWNsa19lbmFibGUoaG9zdC0+aWNsayk7Cgl9CgoJaWYgKCFjcHVfaXNfb21hcDI0eHgoKSkKCQlob3N0LT5mY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2NrIik7CgllbHNlCgkJaG9zdC0+ZmNsayA9IGNsa19nZXQoJnBkZXYtPmRldiwgIm1tY19mY2siKTsKCglpZiAoSVNfRVJSKGhvc3QtPmZjbGspKSB7CgkJcmV0ID0gUFRSX0VSUihob3N0LT5mY2xrKTsKCQlnb3RvIGVycl9mcmVlX2ljbGs7Cgl9CgoJLyogUkVWSVNJVDoKCSAqIEFsc28sIHVzZSBtaW5mby0+Y292ZXIgdG8gZGVjaWRlIGhvdyB0byBtYW5hZ2UKCSAqIHRoZSBjYXJkIGRldGVjdCBzZW5zaW5nLgoJICovCglob3N0LT5wb3dlcl9waW4gPSBtaW5mby0+cG93ZXJfcGluOwoJaG9zdC0+c3dpdGNoX3BpbiA9IG1pbmZvLT5zd2l0Y2hfcGluOwoJaG9zdC0+d3BfcGluID0gbWluZm8tPndwX3BpbjsKCWhvc3QtPnVzZV9kbWEgPSAxOwoJaG9zdC0+ZG1hX2NoID0gLTE7CgoJaG9zdC0+aXJxID0gaXJxOwoJaG9zdC0+cGh5c19iYXNlID0gaG9zdC0+bWVtX3Jlcy0+c3RhcnQ7Cglob3N0LT52aXJ0X2Jhc2UgPSAodm9pZCBfX2lvbWVtICopIElPX0FERFJFU1MoaG9zdC0+cGh5c19iYXNlKTsKCgltbWMtPm9wcyA9ICZtbWNfb21hcF9vcHM7CgltbWMtPmZfbWluID0gNDAwMDAwOwoJbW1jLT5mX21heCA9IDI0MDAwMDAwOwoJbW1jLT5vY3JfYXZhaWwgPSBNTUNfVkREXzMyXzMzIHwgTU1DX1ZERF8zM18zNDsKCW1tYy0+Y2FwcyA9IE1NQ19DQVBfTVVMVElXUklURSB8IE1NQ19DQVBfQllURUJMT0NLOwoKCWlmIChtaW5mby0+d2lyZTQpCgkJIG1tYy0+Y2FwcyB8PSBNTUNfQ0FQXzRfQklUX0RBVEE7CgoJLyogVXNlIHNjYXR0ZXJsaXN0IERNQSB0byByZWR1Y2UgcGVyLXRyYW5zZmVyIGNvc3RzLgoJICogTk9URSBtYXhfc2VnX3NpemUgYXNzdW1wdGlvbiB0aGF0IHNtYWxsIGJsb2NrcyBhcmVuJ3QKCSAqIG5vcm1hbGx5IHVzZWQgKGV4Y2VwdCBlLmcuIGZvciByZWFkaW5nIFNEIHJlZ2lzdGVycykuCgkgKi8KCW1tYy0+bWF4X3BoeXNfc2VncyA9IDMyOwoJbW1jLT5tYXhfaHdfc2VncyA9IDMyOwoJbW1jLT5tYXhfYmxrX3NpemUgPSAyMDQ4OwkvKiBCTEVOIGlzIDExIGJpdHMgKCsxKSAqLwoJbW1jLT5tYXhfYmxrX2NvdW50ID0gMjA0ODsJLyogTkJMSyBpcyAxMSBiaXRzICgrMSkgKi8KCW1tYy0+bWF4X3JlcV9zaXplID0gbW1jLT5tYXhfYmxrX3NpemUgKiBtbWMtPm1heF9ibGtfY291bnQ7CgltbWMtPm1heF9zZWdfc2l6ZSA9IG1tYy0+bWF4X3JlcV9zaXplOwoKCWlmIChob3N0LT5wb3dlcl9waW4gPj0gMCkgewoJCWlmICgocmV0ID0gb21hcF9yZXF1ZXN0X2dwaW8oaG9zdC0+cG93ZXJfcGluKSkgIT0gMCkgewoJCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJCSJVbmFibGUgdG8gZ2V0IEdQSU8gcGluIGZvciBNTUMgcG93ZXJcbiIpOwoJCQlnb3RvIGVycl9mcmVlX2ZjbGs7CgkJfQoJCW9tYXBfc2V0X2dwaW9fZGlyZWN0aW9uKGhvc3QtPnBvd2VyX3BpbiwgMCk7Cgl9CgoJcmV0ID0gcmVxdWVzdF9pcnEoaG9zdC0+aXJxLCBtbWNfb21hcF9pcnEsIDAsIERSSVZFUl9OQU1FLCBob3N0KTsKCWlmIChyZXQpCgkJZ290byBlcnJfZnJlZV9wb3dlcl9ncGlvOwoKCWhvc3QtPmRldiA9ICZwZGV2LT5kZXY7CglwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBob3N0KTsKCglpZiAoaG9zdC0+c3dpdGNoX3BpbiA+PSAwKSB7CgkJSU5JVF9XT1JLKCZob3N0LT5zd2l0Y2hfd29yaywgbW1jX29tYXBfc3dpdGNoX2hhbmRsZXIpOwoJCWluaXRfdGltZXIoJmhvc3QtPnN3aXRjaF90aW1lcik7CgkJaG9zdC0+c3dpdGNoX3RpbWVyLmZ1bmN0aW9uID0gbW1jX29tYXBfc3dpdGNoX3RpbWVyOwoJCWhvc3QtPnN3aXRjaF90aW1lci5kYXRhID0gKHVuc2lnbmVkIGxvbmcpIGhvc3Q7CgkJaWYgKG9tYXBfcmVxdWVzdF9ncGlvKGhvc3QtPnN3aXRjaF9waW4pICE9IDApIHsKCQkJZGV2X3dhcm4obW1jX2Rldihob3N0LT5tbWMpLCAiVW5hYmxlIHRvIGdldCBHUElPIHBpbiBmb3IgTU1DIGNvdmVyIHN3aXRjaFxuIik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZ290byBub19zd2l0Y2g7CgkJfQoKCQlvbWFwX3NldF9ncGlvX2RpcmVjdGlvbihob3N0LT5zd2l0Y2hfcGluLCAxKTsKCQlyZXQgPSByZXF1ZXN0X2lycShPTUFQX0dQSU9fSVJRKGhvc3QtPnN3aXRjaF9waW4pLAoJCQkJICBtbWNfb21hcF9zd2l0Y2hfaXJxLCBJUlFGX1RSSUdHRVJfUklTSU5HLCBEUklWRVJfTkFNRSwgaG9zdCk7CgkJaWYgKHJldCkgewoJCQlkZXZfd2FybihtbWNfZGV2KGhvc3QtPm1tYyksICJVbmFibGUgdG8gZ2V0IElSUSBmb3IgTU1DIGNvdmVyIHN3aXRjaFxuIik7CgkJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnN3aXRjaF9waW4pOwoJCQlob3N0LT5zd2l0Y2hfcGluID0gLTE7CgkJCWdvdG8gbm9fc3dpdGNoOwoJCX0KCQlyZXQgPSBkZXZpY2VfY3JlYXRlX2ZpbGUoJnBkZXYtPmRldiwgJmRldl9hdHRyX2NvdmVyX3N3aXRjaCk7CgkJaWYgKHJldCA9PSAwKSB7CgkJCXJldCA9IGRldmljZV9jcmVhdGVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfZW5hYmxlX3BvbGwpOwoJCQlpZiAocmV0ICE9IDApCgkJCQlkZXZpY2VfcmVtb3ZlX2ZpbGUoJnBkZXYtPmRldiwgJmRldl9hdHRyX2NvdmVyX3N3aXRjaCk7CgkJfQoJCWlmIChyZXQpIHsKCQkJZGV2X3dhcm4obW1jX2Rldihob3N0LT5tbWMpLCAiVW5hYmxlIHRvIGNyZWF0ZSBzeXNmcyBhdHRyaWJ1dGVzXG4iKTsKCQkJZnJlZV9pcnEoT01BUF9HUElPX0lSUShob3N0LT5zd2l0Y2hfcGluKSwgaG9zdCk7CgkJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnN3aXRjaF9waW4pOwoJCQlob3N0LT5zd2l0Y2hfcGluID0gLTE7CgkJCWdvdG8gbm9fc3dpdGNoOwoJCX0KCQlpZiAobW1jX29tYXBfZW5hYmxlX3BvbGwgJiYgbW1jX29tYXBfY292ZXJfaXNfb3Blbihob3N0KSkKCQkJc2NoZWR1bGVfd29yaygmaG9zdC0+c3dpdGNoX3dvcmspOwoJfQoKCW1tY19hZGRfaG9zdChtbWMpOwoKCXJldHVybiAwOwoKbm9fc3dpdGNoOgoJLyogRklYTUU6IEZyZWUgb3RoZXIgcmVzb3VyY2VzIHRvby4gKi8KCWlmIChob3N0KSB7CgkJaWYgKGhvc3QtPmljbGsgJiYgIUlTX0VSUihob3N0LT5pY2xrKSkKCQkJY2xrX3B1dChob3N0LT5pY2xrKTsKCQlpZiAoaG9zdC0+ZmNsayAmJiAhSVNfRVJSKGhvc3QtPmZjbGspKQoJCQljbGtfcHV0KGhvc3QtPmZjbGspOwoJCW1tY19mcmVlX2hvc3QoaG9zdC0+bW1jKTsKCX0KZXJyX2ZyZWVfcG93ZXJfZ3BpbzoKCWlmIChob3N0LT5wb3dlcl9waW4gPj0gMCkKCQlvbWFwX2ZyZWVfZ3Bpbyhob3N0LT5wb3dlcl9waW4pOwplcnJfZnJlZV9mY2xrOgoJY2xrX3B1dChob3N0LT5mY2xrKTsKZXJyX2ZyZWVfaWNsazoKCWlmIChob3N0LT5pY2xrICE9IE5VTEwpIHsKCQljbGtfZGlzYWJsZShob3N0LT5pY2xrKTsKCQljbGtfcHV0KGhvc3QtPmljbGspOwoJfQplcnJfZnJlZV9tbWNfaG9zdDoKCW1tY19mcmVlX2hvc3QoaG9zdC0+bW1jKTsKZXJyX2ZyZWVfbWVtX3JlZ2lvbjoKCXJlbGVhc2VfbWVtX3JlZ2lvbihyZXMtPnN0YXJ0LCByZXMtPmVuZCAtIHJlcy0+c3RhcnQgKyAxKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgbW1jX29tYXBfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CgoJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgTlVMTCk7CgoJQlVHX09OKGhvc3QgPT0gTlVMTCk7CgoJbW1jX3JlbW92ZV9ob3N0KGhvc3QtPm1tYyk7CglmcmVlX2lycShob3N0LT5pcnEsIGhvc3QpOwoKCWlmIChob3N0LT5wb3dlcl9waW4gPj0gMCkKCQlvbWFwX2ZyZWVfZ3Bpbyhob3N0LT5wb3dlcl9waW4pOwoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPj0gMCkgewoJCWRldmljZV9yZW1vdmVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfZW5hYmxlX3BvbGwpOwoJCWRldmljZV9yZW1vdmVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQlmcmVlX2lycShPTUFQX0dQSU9fSVJRKGhvc3QtPnN3aXRjaF9waW4pLCBob3N0KTsKCQlvbWFwX2ZyZWVfZ3Bpbyhob3N0LT5zd2l0Y2hfcGluKTsKCQlob3N0LT5zd2l0Y2hfcGluID0gLTE7CgkJZGVsX3RpbWVyX3N5bmMoJmhvc3QtPnN3aXRjaF90aW1lcik7CgkJZmx1c2hfc2NoZWR1bGVkX3dvcmsoKTsKCX0KCWlmIChob3N0LT5pY2xrICYmICFJU19FUlIoaG9zdC0+aWNsaykpCgkJY2xrX3B1dChob3N0LT5pY2xrKTsKCWlmIChob3N0LT5mY2xrICYmICFJU19FUlIoaG9zdC0+ZmNsaykpCgkJY2xrX3B1dChob3N0LT5mY2xrKTsKCglyZWxlYXNlX21lbV9yZWdpb24ocGRldi0+cmVzb3VyY2VbMF0uc3RhcnQsCgkJCSAgIHBkZXYtPnJlc291cmNlWzBdLmVuZCAtIHBkZXYtPnJlc291cmNlWzBdLnN0YXJ0ICsgMSk7CgoJbW1jX2ZyZWVfaG9zdChob3N0LT5tbWMpOwoKCXJldHVybiAwOwp9CgojaWZkZWYgQ09ORklHX1BNCnN0YXRpYyBpbnQgbW1jX29tYXBfc3VzcGVuZChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LCBwbV9tZXNzYWdlX3QgbWVzZykKewoJaW50IHJldCA9IDA7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwoKCWlmIChob3N0ICYmIGhvc3QtPnN1c3BlbmRlZCkKCQlyZXR1cm4gMDsKCglpZiAoaG9zdCkgewoJCXJldCA9IG1tY19zdXNwZW5kX2hvc3QoaG9zdC0+bW1jLCBtZXNnKTsKCQlpZiAocmV0ID09IDApCgkJCWhvc3QtPnN1c3BlbmRlZCA9IDE7Cgl9CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IG1tY19vbWFwX3Jlc3VtZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CgoJaWYgKGhvc3QgJiYgIWhvc3QtPnN1c3BlbmRlZCkKCQlyZXR1cm4gMDsKCglpZiAoaG9zdCkgewoJCXJldCA9IG1tY19yZXN1bWVfaG9zdChob3N0LT5tbWMpOwoJCWlmIChyZXQgPT0gMCkKCQkJaG9zdC0+c3VzcGVuZGVkID0gMDsKCX0KCglyZXR1cm4gcmV0Owp9CiNlbHNlCiNkZWZpbmUgbW1jX29tYXBfc3VzcGVuZAlOVUxMCiNkZWZpbmUgbW1jX29tYXBfcmVzdW1lCQlOVUxMCiNlbmRpZgoKc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbW1jX29tYXBfZHJpdmVyID0gewoJLnByb2JlCQk9IG1tY19vbWFwX3Byb2JlLAoJLnJlbW92ZQkJPSBtbWNfb21hcF9yZW1vdmUsCgkuc3VzcGVuZAk9IG1tY19vbWFwX3N1c3BlbmQsCgkucmVzdW1lCQk9IG1tY19vbWFwX3Jlc3VtZSwKCS5kcml2ZXIJCT0gewoJCS5uYW1lCT0gRFJJVkVSX05BTUUsCgl9LAp9OwoKc3RhdGljIGludCBfX2luaXQgbW1jX29tYXBfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVyKCZtbWNfb21hcF9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgbW1jX29tYXBfZXhpdCh2b2lkKQp7CglwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmbW1jX29tYXBfZHJpdmVyKTsKfQoKbW9kdWxlX2luaXQobW1jX29tYXBfaW5pdCk7Cm1vZHVsZV9leGl0KG1tY19vbWFwX2V4aXQpOwoKTU9EVUxFX0RFU0NSSVBUSU9OKCJPTUFQIE11bHRpbWVkaWEgQ2FyZCBkcml2ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfQUxJQVMoRFJJVkVSX05BTUUpOwpNT0RVTEVfQVVUSE9SKCJKdWhhIFlyavZs5CIpOwo=