LyoKICogT01BUDIgTWNTUEkgY29udHJvbGxlciBkcml2ZXIKICoKICogQ29weXJpZ2h0IChDKSAyMDA1LCAyMDA2IE5va2lhIENvcnBvcmF0aW9uCiAqIEF1dGhvcjoJU2FtdWVsIE9ydGl6IDxzYW11ZWwub3J0aXpAbm9raWEuY29tPiBhbmQKICoJCUp1aGEgWXJq9mzkIDxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICoKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgojaW5jbHVkZSA8bGludXgvZXJyLmg+CiNpbmNsdWRlIDxsaW51eC9jbGsuaD4KI2luY2x1ZGUgPGxpbnV4L2lvLmg+CgojaW5jbHVkZSA8bGludXgvc3BpL3NwaS5oPgoKI2luY2x1ZGUgPHBsYXQvZG1hLmg+CiNpbmNsdWRlIDxwbGF0L2Nsb2NrLmg+CgoKI2RlZmluZSBPTUFQMl9NQ1NQSV9NQVhfRlJFUQkJNDgwMDAwMDAKCi8qIE9NQVAyIGhhcyAzIFNQSSBjb250cm9sbGVycywgd2hpbGUgT01BUDMgaGFzIDQgKi8KI2RlZmluZSBPTUFQMl9NQ1NQSV9NQVhfQ1RSTCAJCTQKCiNkZWZpbmUgT01BUDJfTUNTUElfUkVWSVNJT04JCTB4MDAKI2RlZmluZSBPTUFQMl9NQ1NQSV9TWVNDT05GSUcJCTB4MTAKI2RlZmluZSBPTUFQMl9NQ1NQSV9TWVNTVEFUVVMJCTB4MTQKI2RlZmluZSBPTUFQMl9NQ1NQSV9JUlFTVEFUVVMJCTB4MTgKI2RlZmluZSBPTUFQMl9NQ1NQSV9JUlFFTkFCTEUJCTB4MWMKI2RlZmluZSBPTUFQMl9NQ1NQSV9XQUtFVVBFTkFCTEUJMHgyMAojZGVmaW5lIE9NQVAyX01DU1BJX1NZU1QJCTB4MjQKI2RlZmluZSBPTUFQMl9NQ1NQSV9NT0RVTENUUkwJCTB4MjgKCi8qIHBlci1jaGFubmVsIGJhbmtzLCAweDE0IGJ5dGVzIGVhY2gsIGZpcnN0IGlzOiAqLwojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORjAJCTB4MmMKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSFNUQVQwCQkweDMwCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDVFJMMAkJMHgzNAojZGVmaW5lIE9NQVAyX01DU1BJX1RYMAkJCTB4MzgKI2RlZmluZSBPTUFQMl9NQ1NQSV9SWDAJCQkweDNjCgovKiBwZXItcmVnaXN0ZXIgYml0bWFza3M6ICovCgojZGVmaW5lIE9NQVAyX01DU1BJX1NZU0NPTkZJR19TTUFSVElETEUJQklUKDQpCiNkZWZpbmUgT01BUDJfTUNTUElfU1lTQ09ORklHX0VOQVdBS0VVUAlCSVQoMikKI2RlZmluZSBPTUFQMl9NQ1NQSV9TWVNDT05GSUdfQVVUT0lETEUJQklUKDApCiNkZWZpbmUgT01BUDJfTUNTUElfU1lTQ09ORklHX1NPRlRSRVNFVAlCSVQoMSkKCiNkZWZpbmUgT01BUDJfTUNTUElfU1lTU1RBVFVTX1JFU0VURE9ORQlCSVQoMCkKCiNkZWZpbmUgT01BUDJfTUNTUElfTU9EVUxDVFJMX1NJTkdMRQlCSVQoMCkKI2RlZmluZSBPTUFQMl9NQ1NQSV9NT0RVTENUUkxfTVMJQklUKDIpCiNkZWZpbmUgT01BUDJfTUNTUElfTU9EVUxDVFJMX1NURVNUCUJJVCgzKQoKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfUEhBCQlCSVQoMCkKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfUE9MCQlCSVQoMSkKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfQ0xLRF9NQVNLCSgweDBmIDw8IDIpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX0VQT0wJCUJJVCg2KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9XTF9NQVNLCSgweDFmIDw8IDcpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX1RSTV9SWF9PTkxZCUJJVCgxMikKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfVFJNX1RYX09OTFkJQklUKDEzKQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9UUk1fTUFTSwkoMHgwMyA8PCAxMikKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfRE1BVwkJQklUKDE0KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9ETUFSCQlCSVQoMTUpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX0RQRTAJCUJJVCgxNikKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfRFBFMQkJQklUKDE3KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9JUwkJQklUKDE4KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9UVVJCTwlCSVQoMTkpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX0ZPUkNFCUJJVCgyMCkKCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hTVEFUX1JYUwkJQklUKDApCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hTVEFUX1RYUwkJQklUKDEpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hTVEFUX0VPVAkJQklUKDIpCgojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ1RSTF9FTgkJQklUKDApCgojZGVmaW5lIE9NQVAyX01DU1BJX1dBS0VVUEVOQUJMRV9XS0VOCUJJVCgwKQoKLyogV2UgaGF2ZSAyIERNQSBjaGFubmVscyBwZXIgQ1MsIG9uZSBmb3IgUlggYW5kIG9uZSBmb3IgVFggKi8Kc3RydWN0IG9tYXAyX21jc3BpX2RtYSB7CglpbnQgZG1hX3R4X2NoYW5uZWw7CglpbnQgZG1hX3J4X2NoYW5uZWw7CgoJaW50IGRtYV90eF9zeW5jX2RldjsKCWludCBkbWFfcnhfc3luY19kZXY7CgoJc3RydWN0IGNvbXBsZXRpb24gZG1hX3R4X2NvbXBsZXRpb247CglzdHJ1Y3QgY29tcGxldGlvbiBkbWFfcnhfY29tcGxldGlvbjsKfTsKCi8qIHVzZSBQSU8gZm9yIHNtYWxsIHRyYW5zZmVycywgYXZvaWRpbmcgRE1BIHNldHVwL3RlYXJkb3duIG92ZXJoZWFkIGFuZAogKiBjYWNoZSBvcGVyYXRpb25zOyBiZXR0ZXIgaGV1cmlzdGljcyBjb25zaWRlciB3b3Jkc2l6ZSBhbmQgYml0cmF0ZS4KICovCiNkZWZpbmUgRE1BX01JTl9CWVRFUwkJCTgKCgpzdHJ1Y3Qgb21hcDJfbWNzcGkgewoJc3RydWN0IHdvcmtfc3RydWN0CXdvcms7CgkvKiBsb2NrIHByb3RlY3RzIHF1ZXVlIGFuZCByZWdpc3RlcnMgKi8KCXNwaW5sb2NrX3QJCWxvY2s7CglzdHJ1Y3QgbGlzdF9oZWFkCW1zZ19xdWV1ZTsKCXN0cnVjdCBzcGlfbWFzdGVyCSptYXN0ZXI7CglzdHJ1Y3QgY2xrCQkqaWNrOwoJc3RydWN0IGNsawkJKmZjazsKCS8qIFZpcnR1YWwgYmFzZSBhZGRyZXNzIG9mIHRoZSBjb250cm9sbGVyICovCgl2b2lkIF9faW9tZW0JCSpiYXNlOwoJdW5zaWduZWQgbG9uZwkJcGh5czsKCS8qIFNQSTEgaGFzIDQgY2hhbm5lbHMsIHdoaWxlIFNQSTIgaGFzIDIgKi8KCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKmRtYV9jaGFubmVsczsKfTsKCnN0cnVjdCBvbWFwMl9tY3NwaV9jcyB7Cgl2b2lkIF9faW9tZW0JCSpiYXNlOwoJdW5zaWduZWQgbG9uZwkJcGh5czsKCWludAkJCXdvcmRfbGVuOwoJc3RydWN0IGxpc3RfaGVhZAlub2RlOwoJLyogQ29udGV4dCBzYXZlIGFuZCByZXN0b3JlIHNoYWRvdyByZWdpc3RlciAqLwoJdTMyCQkJY2hjb25mMDsKfTsKCi8qIHVzZWQgZm9yIGNvbnRleHQgc2F2ZSBhbmQgcmVzdG9yZSwgc3RydWN0dXJlIG1lbWJlcnMgdG8gYmUgdXBkYXRlZCB3aGVuZXZlcgogKiBjb3JyZXNwb25kaW5nIHJlZ2lzdGVycyBhcmUgbW9kaWZpZWQuCiAqLwpzdHJ1Y3Qgb21hcDJfbWNzcGlfcmVncyB7Cgl1MzIgc3lzY29uZmlnOwoJdTMyIG1vZHVsY3RybDsKCXUzMiB3YWtldXBlbmFibGU7CglzdHJ1Y3QgbGlzdF9oZWFkIGNzOwp9OwoKc3RhdGljIHN0cnVjdCBvbWFwMl9tY3NwaV9yZWdzIG9tYXAyX21jc3BpX2N0eFtPTUFQMl9NQ1NQSV9NQVhfQ1RSTF07CgpzdGF0aWMgc3RydWN0IHdvcmtxdWV1ZV9zdHJ1Y3QgKm9tYXAyX21jc3BpX3dxOwoKI2RlZmluZSBNT0RfUkVHX0JJVCh2YWwsIG1hc2ssIHNldCkgZG8geyBcCglpZiAoc2V0KSBcCgkJdmFsIHw9IG1hc2s7IFwKCWVsc2UgXAoJCXZhbCAmPSB+bWFzazsgXAp9IHdoaWxlICgwKQoKc3RhdGljIGlubGluZSB2b2lkIG1jc3BpX3dyaXRlX3JlZyhzdHJ1Y3Qgc3BpX21hc3RlciAqbWFzdGVyLAoJCWludCBpZHgsIHUzMiB2YWwpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaSAqbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKG1hc3Rlcik7CgoJX19yYXdfd3JpdGVsKHZhbCwgbWNzcGktPmJhc2UgKyBpZHgpOwp9CgpzdGF0aWMgaW5saW5lIHUzMiBtY3NwaV9yZWFkX3JlZyhzdHJ1Y3Qgc3BpX21hc3RlciAqbWFzdGVyLCBpbnQgaWR4KQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGkgKm1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShtYXN0ZXIpOwoKCXJldHVybiBfX3Jhd19yZWFkbChtY3NwaS0+YmFzZSArIGlkeCk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtY3NwaV93cml0ZV9jc19yZWcoY29uc3Qgc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwKCQlpbnQgaWR4LCB1MzIgdmFsKQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJKmNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoKCV9fcmF3X3dyaXRlbCh2YWwsIGNzLT5iYXNlICsgIGlkeCk7Cn0KCnN0YXRpYyBpbmxpbmUgdTMyIG1jc3BpX3JlYWRfY3NfcmVnKGNvbnN0IHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIGludCBpZHgpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaV9jcwkqY3MgPSBzcGktPmNvbnRyb2xsZXJfc3RhdGU7CgoJcmV0dXJuIF9fcmF3X3JlYWRsKGNzLT5iYXNlICsgaWR4KTsKfQoKc3RhdGljIGlubGluZSB1MzIgbWNzcGlfY2FjaGVkX2NoY29uZjAoY29uc3Qgc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKewoJc3RydWN0IG9tYXAyX21jc3BpX2NzICpjcyA9IHNwaS0+Y29udHJvbGxlcl9zdGF0ZTsKCglyZXR1cm4gY3MtPmNoY29uZjA7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtY3NwaV93cml0ZV9jaGNvbmYwKGNvbnN0IHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIHUzMiB2YWwpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaV9jcyAqY3MgPSBzcGktPmNvbnRyb2xsZXJfc3RhdGU7CgoJY3MtPmNoY29uZjAgPSB2YWw7CgltY3NwaV93cml0ZV9jc19yZWcoc3BpLCBPTUFQMl9NQ1NQSV9DSENPTkYwLCB2YWwpOwp9CgpzdGF0aWMgdm9pZCBvbWFwMl9tY3NwaV9zZXRfZG1hX3JlcShjb25zdCBzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLAoJCWludCBpc19yZWFkLCBpbnQgZW5hYmxlKQp7Cgl1MzIgbCwgcnc7CgoJbCA9IG1jc3BpX2NhY2hlZF9jaGNvbmYwKHNwaSk7CgoJaWYgKGlzX3JlYWQpIC8qIDEgaXMgcmVhZCwgMCB3cml0ZSAqLwoJCXJ3ID0gT01BUDJfTUNTUElfQ0hDT05GX0RNQVI7CgllbHNlCgkJcncgPSBPTUFQMl9NQ1NQSV9DSENPTkZfRE1BVzsKCglNT0RfUkVHX0JJVChsLCBydywgZW5hYmxlKTsKCW1jc3BpX3dyaXRlX2NoY29uZjAoc3BpLCBsKTsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfc2V0X2VuYWJsZShjb25zdCBzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBpbnQgZW5hYmxlKQp7Cgl1MzIgbDsKCglsID0gZW5hYmxlID8gT01BUDJfTUNTUElfQ0hDVFJMX0VOIDogMDsKCW1jc3BpX3dyaXRlX2NzX3JlZyhzcGksIE9NQVAyX01DU1BJX0NIQ1RSTDAsIGwpOwp9CgpzdGF0aWMgdm9pZCBvbWFwMl9tY3NwaV9mb3JjZV9jcyhzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBpbnQgY3NfYWN0aXZlKQp7Cgl1MzIgbDsKCglsID0gbWNzcGlfY2FjaGVkX2NoY29uZjAoc3BpKTsKCU1PRF9SRUdfQklUKGwsIE9NQVAyX01DU1BJX0NIQ09ORl9GT1JDRSwgY3NfYWN0aXZlKTsKCW1jc3BpX3dyaXRlX2NoY29uZjAoc3BpLCBsKTsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfc2V0X21hc3Rlcl9tb2RlKHN0cnVjdCBzcGlfbWFzdGVyICptYXN0ZXIpCnsKCXUzMiBsOwoKCS8qIHNldHVwIHdoZW4gc3dpdGNoaW5nIGZyb20gKHJlc2V0IGRlZmF1bHQpIHNsYXZlIG1vZGUKCSAqIHRvIHNpbmdsZS1jaGFubmVsIG1hc3RlciBtb2RlCgkgKi8KCWwgPSBtY3NwaV9yZWFkX3JlZyhtYXN0ZXIsIE9NQVAyX01DU1BJX01PRFVMQ1RSTCk7CglNT0RfUkVHX0JJVChsLCBPTUFQMl9NQ1NQSV9NT0RVTENUUkxfU1RFU1QsIDApOwoJTU9EX1JFR19CSVQobCwgT01BUDJfTUNTUElfTU9EVUxDVFJMX01TLCAwKTsKCU1PRF9SRUdfQklUKGwsIE9NQVAyX01DU1BJX01PRFVMQ1RSTF9TSU5HTEUsIDEpOwoJbWNzcGlfd3JpdGVfcmVnKG1hc3RlciwgT01BUDJfTUNTUElfTU9EVUxDVFJMLCBsKTsKCglvbWFwMl9tY3NwaV9jdHhbbWFzdGVyLT5idXNfbnVtIC0gMV0ubW9kdWxjdHJsID0gbDsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfcmVzdG9yZV9jdHgoc3RydWN0IG9tYXAyX21jc3BpICptY3NwaSkKewoJc3RydWN0IHNwaV9tYXN0ZXIgKnNwaV9jbnRybDsKCXN0cnVjdCBvbWFwMl9tY3NwaV9jcyAqY3M7CglzcGlfY250cmwgPSBtY3NwaS0+bWFzdGVyOwoKCS8qIE1jU1BJOiBjb250ZXh0IHJlc3RvcmUgKi8KCW1jc3BpX3dyaXRlX3JlZyhzcGlfY250cmwsIE9NQVAyX01DU1BJX01PRFVMQ1RSTCwKCQkJb21hcDJfbWNzcGlfY3R4W3NwaV9jbnRybC0+YnVzX251bSAtIDFdLm1vZHVsY3RybCk7CgoJbWNzcGlfd3JpdGVfcmVnKHNwaV9jbnRybCwgT01BUDJfTUNTUElfU1lTQ09ORklHLAoJCQlvbWFwMl9tY3NwaV9jdHhbc3BpX2NudHJsLT5idXNfbnVtIC0gMV0uc3lzY29uZmlnKTsKCgltY3NwaV93cml0ZV9yZWcoc3BpX2NudHJsLCBPTUFQMl9NQ1NQSV9XQUtFVVBFTkFCTEUsCgkJCW9tYXAyX21jc3BpX2N0eFtzcGlfY250cmwtPmJ1c19udW0gLSAxXS53YWtldXBlbmFibGUpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoY3MsICZvbWFwMl9tY3NwaV9jdHhbc3BpX2NudHJsLT5idXNfbnVtIC0gMV0uY3MsCgkJCW5vZGUpCgkJX19yYXdfd3JpdGVsKGNzLT5jaGNvbmYwLCBjcy0+YmFzZSArIE9NQVAyX01DU1BJX0NIQ09ORjApOwp9CnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX2Rpc2FibGVfY2xvY2tzKHN0cnVjdCBvbWFwMl9tY3NwaSAqbWNzcGkpCnsKCWNsa19kaXNhYmxlKG1jc3BpLT5pY2spOwoJY2xrX2Rpc2FibGUobWNzcGktPmZjayk7Cn0KCnN0YXRpYyBpbnQgb21hcDJfbWNzcGlfZW5hYmxlX2Nsb2NrcyhzdHJ1Y3Qgb21hcDJfbWNzcGkgKm1jc3BpKQp7CglpZiAoY2xrX2VuYWJsZShtY3NwaS0+aWNrKSkKCQlyZXR1cm4gLUVOT0RFVjsKCWlmIChjbGtfZW5hYmxlKG1jc3BpLT5mY2spKQoJCXJldHVybiAtRU5PREVWOwoKCW9tYXAyX21jc3BpX3Jlc3RvcmVfY3R4KG1jc3BpKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHVuc2lnbmVkCm9tYXAyX21jc3BpX3R4cnhfZG1hKHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIHN0cnVjdCBzcGlfdHJhbnNmZXIgKnhmZXIpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJKmNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoJc3RydWN0IG9tYXAyX21jc3BpX2RtYSAgKm1jc3BpX2RtYTsKCXVuc2lnbmVkIGludAkJY291bnQsIGM7Cgl1bnNpZ25lZCBsb25nCQliYXNlLCB0eF9yZWcsIHJ4X3JlZzsKCWludAkJCXdvcmRfbGVuLCBkYXRhX3R5cGUsIGVsZW1lbnRfY291bnQ7Cgl1OAkJCSogcng7Cgljb25zdCB1OAkJKiB0eDsKCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEoc3BpLT5tYXN0ZXIpOwoJbWNzcGlfZG1hID0gJm1jc3BpLT5kbWFfY2hhbm5lbHNbc3BpLT5jaGlwX3NlbGVjdF07CgoJY291bnQgPSB4ZmVyLT5sZW47CgljID0gY291bnQ7Cgl3b3JkX2xlbiA9IGNzLT53b3JkX2xlbjsKCgliYXNlID0gY3MtPnBoeXM7Cgl0eF9yZWcgPSBiYXNlICsgT01BUDJfTUNTUElfVFgwOwoJcnhfcmVnID0gYmFzZSArIE9NQVAyX01DU1BJX1JYMDsKCXJ4ID0geGZlci0+cnhfYnVmOwoJdHggPSB4ZmVyLT50eF9idWY7CgoJaWYgKHdvcmRfbGVuIDw9IDgpIHsKCQlkYXRhX3R5cGUgPSBPTUFQX0RNQV9EQVRBX1RZUEVfUzg7CgkJZWxlbWVudF9jb3VudCA9IGNvdW50OwoJfSBlbHNlIGlmICh3b3JkX2xlbiA8PSAxNikgewoJCWRhdGFfdHlwZSA9IE9NQVBfRE1BX0RBVEFfVFlQRV9TMTY7CgkJZWxlbWVudF9jb3VudCA9IGNvdW50ID4+IDE7Cgl9IGVsc2UgLyogd29yZF9sZW4gPD0gMzIgKi8gewoJCWRhdGFfdHlwZSA9IE9NQVBfRE1BX0RBVEFfVFlQRV9TMzI7CgkJZWxlbWVudF9jb3VudCA9IGNvdW50ID4+IDI7Cgl9CgoJaWYgKHR4ICE9IE5VTEwpIHsKCQlvbWFwX3NldF9kbWFfdHJhbnNmZXJfcGFyYW1zKG1jc3BpX2RtYS0+ZG1hX3R4X2NoYW5uZWwsCgkJCQlkYXRhX3R5cGUsIGVsZW1lbnRfY291bnQsIDEsCgkJCQlPTUFQX0RNQV9TWU5DX0VMRU1FTlQsCgkJCQltY3NwaV9kbWEtPmRtYV90eF9zeW5jX2RldiwgMCk7CgoJCW9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyhtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsLCAwLAoJCQkJT01BUF9ETUFfQU1PREVfQ09OU1RBTlQsCgkJCQl0eF9yZWcsIDAsIDApOwoKCQlvbWFwX3NldF9kbWFfc3JjX3BhcmFtcyhtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsLCAwLAoJCQkJT01BUF9ETUFfQU1PREVfUE9TVF9JTkMsCgkJCQl4ZmVyLT50eF9kbWEsIDAsIDApOwoJfQoKCWlmIChyeCAhPSBOVUxMKSB7CgkJb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhtY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsLAoJCQkJZGF0YV90eXBlLCBlbGVtZW50X2NvdW50IC0gMSwgMSwKCQkJCU9NQVBfRE1BX1NZTkNfRUxFTUVOVCwKCQkJCW1jc3BpX2RtYS0+ZG1hX3J4X3N5bmNfZGV2LCAxKTsKCgkJb21hcF9zZXRfZG1hX3NyY19wYXJhbXMobWNzcGlfZG1hLT5kbWFfcnhfY2hhbm5lbCwgMCwKCQkJCU9NQVBfRE1BX0FNT0RFX0NPTlNUQU5ULAoJCQkJcnhfcmVnLCAwLCAwKTsKCgkJb21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwsIDAsCgkJCQlPTUFQX0RNQV9BTU9ERV9QT1NUX0lOQywKCQkJCXhmZXItPnJ4X2RtYSwgMCwgMCk7Cgl9CgoJaWYgKHR4ICE9IE5VTEwpIHsKCQlvbWFwX3N0YXJ0X2RtYShtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsKTsKCQlvbWFwMl9tY3NwaV9zZXRfZG1hX3JlcShzcGksIDAsIDEpOwoJfQoKCWlmIChyeCAhPSBOVUxMKSB7CgkJb21hcF9zdGFydF9kbWEobWNzcGlfZG1hLT5kbWFfcnhfY2hhbm5lbCk7CgkJb21hcDJfbWNzcGlfc2V0X2RtYV9yZXEoc3BpLCAxLCAxKTsKCX0KCglpZiAodHggIT0gTlVMTCkgewoJCXdhaXRfZm9yX2NvbXBsZXRpb24oJm1jc3BpX2RtYS0+ZG1hX3R4X2NvbXBsZXRpb24pOwoJCWRtYV91bm1hcF9zaW5nbGUoTlVMTCwgeGZlci0+dHhfZG1hLCBjb3VudCwgRE1BX1RPX0RFVklDRSk7Cgl9CgoJaWYgKHJ4ICE9IE5VTEwpIHsKCQl3YWl0X2Zvcl9jb21wbGV0aW9uKCZtY3NwaV9kbWEtPmRtYV9yeF9jb21wbGV0aW9uKTsKCQlkbWFfdW5tYXBfc2luZ2xlKE5VTEwsIHhmZXItPnJ4X2RtYSwgY291bnQsIERNQV9GUk9NX0RFVklDRSk7CgkJb21hcDJfbWNzcGlfc2V0X2VuYWJsZShzcGksIDApOwoJCWlmIChsaWtlbHkobWNzcGlfcmVhZF9jc19yZWcoc3BpLCBPTUFQMl9NQ1NQSV9DSFNUQVQwKQoJCQkJJiBPTUFQMl9NQ1NQSV9DSFNUQVRfUlhTKSkgewoJCQl1MzIgdzsKCgkJCXcgPSBtY3NwaV9yZWFkX2NzX3JlZyhzcGksIE9NQVAyX01DU1BJX1JYMCk7CgkJCWlmICh3b3JkX2xlbiA8PSA4KQoJCQkJKCh1OCAqKXhmZXItPnJ4X2J1ZilbZWxlbWVudF9jb3VudCAtIDFdID0gdzsKCQkJZWxzZSBpZiAod29yZF9sZW4gPD0gMTYpCgkJCQkoKHUxNiAqKXhmZXItPnJ4X2J1ZilbZWxlbWVudF9jb3VudCAtIDFdID0gdzsKCQkJZWxzZSAvKiB3b3JkX2xlbiA8PSAzMiAqLwoJCQkJKCh1MzIgKil4ZmVyLT5yeF9idWYpW2VsZW1lbnRfY291bnQgLSAxXSA9IHc7CgkJfSBlbHNlIHsKCQkJZGV2X2Vycigmc3BpLT5kZXYsICJETUEgUlggbGFzdCB3b3JkIGVtcHR5Iik7CgkJCWNvdW50IC09ICh3b3JkX2xlbiA8PSA4KSAgPyAxIDoKCQkJCSAod29yZF9sZW4gPD0gMTYpID8gMiA6CgkJCSAgICAgICAvKiB3b3JkX2xlbiA8PSAzMiAqLyA0OwoJCX0KCQlvbWFwMl9tY3NwaV9zZXRfZW5hYmxlKHNwaSwgMSk7Cgl9CglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBpbnQgbWNzcGlfd2FpdF9mb3JfcmVnX2JpdCh2b2lkIF9faW9tZW0gKnJlZywgdW5zaWduZWQgbG9uZyBiaXQpCnsKCXVuc2lnbmVkIGxvbmcgdGltZW91dDsKCgl0aW1lb3V0ID0gamlmZmllcyArIG1zZWNzX3RvX2ppZmZpZXMoMTAwMCk7Cgl3aGlsZSAoIShfX3Jhd19yZWFkbChyZWcpICYgYml0KSkgewoJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVvdXQpKQoJCQlyZXR1cm4gLTE7CgkJY3B1X3JlbGF4KCk7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIHVuc2lnbmVkCm9tYXAyX21jc3BpX3R4cnhfcGlvKHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIHN0cnVjdCBzcGlfdHJhbnNmZXIgKnhmZXIpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJKmNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoJdW5zaWduZWQgaW50CQljb3VudCwgYzsKCXUzMgkJCWw7Cgl2b2lkIF9faW9tZW0JCSpiYXNlID0gY3MtPmJhc2U7Cgl2b2lkIF9faW9tZW0JCSp0eF9yZWc7Cgl2b2lkIF9faW9tZW0JCSpyeF9yZWc7Cgl2b2lkIF9faW9tZW0JCSpjaHN0YXRfcmVnOwoJaW50CQkJd29yZF9sZW47CgoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKHNwaS0+bWFzdGVyKTsKCWNvdW50ID0geGZlci0+bGVuOwoJYyA9IGNvdW50OwoJd29yZF9sZW4gPSBjcy0+d29yZF9sZW47CgoJbCA9IG1jc3BpX2NhY2hlZF9jaGNvbmYwKHNwaSk7CglsICY9IH5PTUFQMl9NQ1NQSV9DSENPTkZfVFJNX01BU0s7CgoJLyogV2Ugc3RvcmUgdGhlIHByZS1jYWxjdWxhdGVkIHJlZ2lzdGVyIGFkZHJlc3NlcyBvbiBzdGFjayB0byBzcGVlZAoJICogdXAgdGhlIHRyYW5zZmVyIGxvb3AuICovCgl0eF9yZWcJCT0gYmFzZSArIE9NQVAyX01DU1BJX1RYMDsKCXJ4X3JlZwkJPSBiYXNlICsgT01BUDJfTUNTUElfUlgwOwoJY2hzdGF0X3JlZwk9IGJhc2UgKyBPTUFQMl9NQ1NQSV9DSFNUQVQwOwoKCWlmICh3b3JkX2xlbiA8PSA4KSB7CgkJdTgJCSpyeDsKCQljb25zdCB1OAkqdHg7CgoJCXJ4ID0geGZlci0+cnhfYnVmOwoJCXR4ID0geGZlci0+dHhfYnVmOwoKCQlkbyB7CgkJCWMgLT0gMTsKCQkJaWYgKHR4ICE9IE5VTEwpIHsKCQkJCWlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9UWFMpIDwgMCkgewoJCQkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiVFhTIHRpbWVkIG91dFxuIik7CgkJCQkJZ290byBvdXQ7CgkJCQl9CiNpZmRlZiBWRVJCT1NFCgkJCQlkZXZfZGJnKCZzcGktPmRldiwgIndyaXRlLSVkICUwMnhcbiIsCgkJCQkJCXdvcmRfbGVuLCAqdHgpOwojZW5kaWYKCQkJCV9fcmF3X3dyaXRlbCgqdHgrKywgdHhfcmVnKTsKCQkJfQoJCQlpZiAocnggIT0gTlVMTCkgewoJCQkJaWYgKG1jc3BpX3dhaXRfZm9yX3JlZ19iaXQoY2hzdGF0X3JlZywKCQkJCQkJT01BUDJfTUNTUElfQ0hTVEFUX1JYUykgPCAwKSB7CgkJCQkJZGV2X2Vycigmc3BpLT5kZXYsICJSWFMgdGltZWQgb3V0XG4iKTsKCQkJCQlnb3RvIG91dDsKCQkJCX0KCQkJCS8qIHByZXZlbnQgbGFzdCBSWF9PTkxZIHJlYWQgZnJvbSB0cmlnZ2VyaW5nCgkJCQkgKiBtb3JlIHdvcmQgaS9vOiBzd2l0Y2ggdG8gcngrdHgKCQkJCSAqLwoJCQkJaWYgKGMgPT0gMCAmJiB0eCA9PSBOVUxMKQoJCQkJCW1jc3BpX3dyaXRlX2NoY29uZjAoc3BpLCBsKTsKCQkJCSpyeCsrID0gX19yYXdfcmVhZGwocnhfcmVnKTsKI2lmZGVmIFZFUkJPU0UKCQkJCWRldl9kYmcoJnNwaS0+ZGV2LCAicmVhZC0lZCAlMDJ4XG4iLAoJCQkJCQl3b3JkX2xlbiwgKihyeCAtIDEpKTsKI2VuZGlmCgkJCX0KCQl9IHdoaWxlIChjKTsKCX0gZWxzZSBpZiAod29yZF9sZW4gPD0gMTYpIHsKCQl1MTYJCSpyeDsKCQljb25zdCB1MTYJKnR4OwoKCQlyeCA9IHhmZXItPnJ4X2J1ZjsKCQl0eCA9IHhmZXItPnR4X2J1ZjsKCQlkbyB7CgkJCWMgLT0gMjsKCQkJaWYgKHR4ICE9IE5VTEwpIHsKCQkJCWlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9UWFMpIDwgMCkgewoJCQkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiVFhTIHRpbWVkIG91dFxuIik7CgkJCQkJZ290byBvdXQ7CgkJCQl9CiNpZmRlZiBWRVJCT1NFCgkJCQlkZXZfZGJnKCZzcGktPmRldiwgIndyaXRlLSVkICUwNHhcbiIsCgkJCQkJCXdvcmRfbGVuLCAqdHgpOwojZW5kaWYKCQkJCV9fcmF3X3dyaXRlbCgqdHgrKywgdHhfcmVnKTsKCQkJfQoJCQlpZiAocnggIT0gTlVMTCkgewoJCQkJaWYgKG1jc3BpX3dhaXRfZm9yX3JlZ19iaXQoY2hzdGF0X3JlZywKCQkJCQkJT01BUDJfTUNTUElfQ0hTVEFUX1JYUykgPCAwKSB7CgkJCQkJZGV2X2Vycigmc3BpLT5kZXYsICJSWFMgdGltZWQgb3V0XG4iKTsKCQkJCQlnb3RvIG91dDsKCQkJCX0KCQkJCS8qIHByZXZlbnQgbGFzdCBSWF9PTkxZIHJlYWQgZnJvbSB0cmlnZ2VyaW5nCgkJCQkgKiBtb3JlIHdvcmQgaS9vOiBzd2l0Y2ggdG8gcngrdHgKCQkJCSAqLwoJCQkJaWYgKGMgPT0gMCAmJiB0eCA9PSBOVUxMKQoJCQkJCW1jc3BpX3dyaXRlX2NoY29uZjAoc3BpLCBsKTsKCQkJCSpyeCsrID0gX19yYXdfcmVhZGwocnhfcmVnKTsKI2lmZGVmIFZFUkJPU0UKCQkJCWRldl9kYmcoJnNwaS0+ZGV2LCAicmVhZC0lZCAlMDR4XG4iLAoJCQkJCQl3b3JkX2xlbiwgKihyeCAtIDEpKTsKI2VuZGlmCgkJCX0KCQl9IHdoaWxlIChjKTsKCX0gZWxzZSBpZiAod29yZF9sZW4gPD0gMzIpIHsKCQl1MzIJCSpyeDsKCQljb25zdCB1MzIJKnR4OwoKCQlyeCA9IHhmZXItPnJ4X2J1ZjsKCQl0eCA9IHhmZXItPnR4X2J1ZjsKCQlkbyB7CgkJCWMgLT0gNDsKCQkJaWYgKHR4ICE9IE5VTEwpIHsKCQkJCWlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9UWFMpIDwgMCkgewoJCQkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiVFhTIHRpbWVkIG91dFxuIik7CgkJCQkJZ290byBvdXQ7CgkJCQl9CiNpZmRlZiBWRVJCT1NFCgkJCQlkZXZfZGJnKCZzcGktPmRldiwgIndyaXRlLSVkICUwNHhcbiIsCgkJCQkJCXdvcmRfbGVuLCAqdHgpOwojZW5kaWYKCQkJCV9fcmF3X3dyaXRlbCgqdHgrKywgdHhfcmVnKTsKCQkJfQoJCQlpZiAocnggIT0gTlVMTCkgewoJCQkJaWYgKG1jc3BpX3dhaXRfZm9yX3JlZ19iaXQoY2hzdGF0X3JlZywKCQkJCQkJT01BUDJfTUNTUElfQ0hTVEFUX1JYUykgPCAwKSB7CgkJCQkJZGV2X2Vycigmc3BpLT5kZXYsICJSWFMgdGltZWQgb3V0XG4iKTsKCQkJCQlnb3RvIG91dDsKCQkJCX0KCQkJCS8qIHByZXZlbnQgbGFzdCBSWF9PTkxZIHJlYWQgZnJvbSB0cmlnZ2VyaW5nCgkJCQkgKiBtb3JlIHdvcmQgaS9vOiBzd2l0Y2ggdG8gcngrdHgKCQkJCSAqLwoJCQkJaWYgKGMgPT0gMCAmJiB0eCA9PSBOVUxMKQoJCQkJCW1jc3BpX3dyaXRlX2NoY29uZjAoc3BpLCBsKTsKCQkJCSpyeCsrID0gX19yYXdfcmVhZGwocnhfcmVnKTsKI2lmZGVmIFZFUkJPU0UKCQkJCWRldl9kYmcoJnNwaS0+ZGV2LCAicmVhZC0lZCAlMDR4XG4iLAoJCQkJCQl3b3JkX2xlbiwgKihyeCAtIDEpKTsKI2VuZGlmCgkJCX0KCQl9IHdoaWxlIChjKTsKCX0KCgkvKiBmb3IgVFhfT05MWSBtb2RlLCBiZSBzdXJlIGFsbCB3b3JkcyBoYXZlIHNoaWZ0ZWQgb3V0ICovCglpZiAoeGZlci0+cnhfYnVmID09IE5VTEwpIHsKCQlpZiAobWNzcGlfd2FpdF9mb3JfcmVnX2JpdChjaHN0YXRfcmVnLAoJCQkJT01BUDJfTUNTUElfQ0hTVEFUX1RYUykgPCAwKSB7CgkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiVFhTIHRpbWVkIG91dFxuIik7CgkJfSBlbHNlIGlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQlPTUFQMl9NQ1NQSV9DSFNUQVRfRU9UKSA8IDApCgkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiRU9UIHRpbWVkIG91dFxuIik7Cgl9Cm91dDoKCXJldHVybiBjb3VudCAtIGM7Cn0KCi8qIGNhbGxlZCBvbmx5IHdoZW4gbm8gdHJhbnNmZXIgaXMgYWN0aXZlIHRvIHRoaXMgZGV2aWNlICovCnN0YXRpYyBpbnQgb21hcDJfbWNzcGlfc2V0dXBfdHJhbnNmZXIoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwKCQlzdHJ1Y3Qgc3BpX3RyYW5zZmVyICp0KQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MgKmNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoJc3RydWN0IG9tYXAyX21jc3BpICptY3NwaTsKCXN0cnVjdCBzcGlfbWFzdGVyICpzcGlfY250cmw7Cgl1MzIgbCA9IDAsIGRpdiA9IDA7Cgl1OCB3b3JkX2xlbiA9IHNwaS0+Yml0c19wZXJfd29yZDsKCXUzMiBzcGVlZF9oeiA9IHNwaS0+bWF4X3NwZWVkX2h6OwoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShzcGktPm1hc3Rlcik7CglzcGlfY250cmwgPSBtY3NwaS0+bWFzdGVyOwoKCWlmICh0ICE9IE5VTEwgJiYgdC0+Yml0c19wZXJfd29yZCkKCQl3b3JkX2xlbiA9IHQtPmJpdHNfcGVyX3dvcmQ7CgoJY3MtPndvcmRfbGVuID0gd29yZF9sZW47CgoJaWYgKHQgJiYgdC0+c3BlZWRfaHopCgkJc3BlZWRfaHogPSB0LT5zcGVlZF9oejsKCglpZiAoc3BlZWRfaHopIHsKCQl3aGlsZSAoZGl2IDw9IDE1ICYmIChPTUFQMl9NQ1NQSV9NQVhfRlJFUSAvICgxIDw8IGRpdikpCgkJCQkJPiBzcGVlZF9oeikKCQkJZGl2Kys7Cgl9IGVsc2UKCQlkaXYgPSAxNTsKCglsID0gbWNzcGlfY2FjaGVkX2NoY29uZjAoc3BpKTsKCgkvKiBzdGFuZGFyZCA0LXdpcmUgbWFzdGVyIG1vZGU6ICBTQ0ssIE1PU0kvb3V0LCBNSVNPL2luLCBuQ1MKCSAqIFJFVklTSVQ6IHRoaXMgY29udHJvbGxlciBjb3VsZCBzdXBwb3J0IFNQSV8zV0lSRSBtb2RlLgoJICovCglsICY9IH4oT01BUDJfTUNTUElfQ0hDT05GX0lTfE9NQVAyX01DU1BJX0NIQ09ORl9EUEUxKTsKCWwgfD0gT01BUDJfTUNTUElfQ0hDT05GX0RQRTA7CgoJLyogd29yZGxlbmd0aCAqLwoJbCAmPSB+T01BUDJfTUNTUElfQ0hDT05GX1dMX01BU0s7CglsIHw9ICh3b3JkX2xlbiAtIDEpIDw8IDc7CgoJLyogc2V0IGNoaXBzZWxlY3QgcG9sYXJpdHk7IG1hbmFnZSB3aXRoIEZPUkNFICovCglpZiAoIShzcGktPm1vZGUgJiBTUElfQ1NfSElHSCkpCgkJbCB8PSBPTUFQMl9NQ1NQSV9DSENPTkZfRVBPTDsJLyogYWN0aXZlLWxvdzsgbm9ybWFsICovCgllbHNlCgkJbCAmPSB+T01BUDJfTUNTUElfQ0hDT05GX0VQT0w7CgoJLyogc2V0IGNsb2NrIGRpdmlzb3IgKi8KCWwgJj0gfk9NQVAyX01DU1BJX0NIQ09ORl9DTEtEX01BU0s7CglsIHw9IGRpdiA8PCAyOwoKCS8qIHNldCBTUEkgbW9kZSAwLi4zICovCglpZiAoc3BpLT5tb2RlICYgU1BJX0NQT0wpCgkJbCB8PSBPTUFQMl9NQ1NQSV9DSENPTkZfUE9MOwoJZWxzZQoJCWwgJj0gfk9NQVAyX01DU1BJX0NIQ09ORl9QT0w7CglpZiAoc3BpLT5tb2RlICYgU1BJX0NQSEEpCgkJbCB8PSBPTUFQMl9NQ1NQSV9DSENPTkZfUEhBOwoJZWxzZQoJCWwgJj0gfk9NQVAyX01DU1BJX0NIQ09ORl9QSEE7CgoJbWNzcGlfd3JpdGVfY2hjb25mMChzcGksIGwpOwoKCWRldl9kYmcoJnNwaS0+ZGV2LCAic2V0dXA6IHNwZWVkICVkLCBzYW1wbGUgJXMgZWRnZSwgY2xrICVzXG4iLAoJCQlPTUFQMl9NQ1NQSV9NQVhfRlJFUSAvICgxIDw8IGRpdiksCgkJCShzcGktPm1vZGUgJiBTUElfQ1BIQSkgPyAidHJhaWxpbmciIDogImxlYWRpbmciLAoJCQkoc3BpLT5tb2RlICYgU1BJX0NQT0wpID8gImludmVydGVkIiA6ICJub3JtYWwiKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfZG1hX3J4X2NhbGxiYWNrKGludCBsY2gsIHUxNiBjaF9zdGF0dXMsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBzcGlfZGV2aWNlCSpzcGkgPSBkYXRhOwoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKm1jc3BpX2RtYTsKCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEoc3BpLT5tYXN0ZXIpOwoJbWNzcGlfZG1hID0gJihtY3NwaS0+ZG1hX2NoYW5uZWxzW3NwaS0+Y2hpcF9zZWxlY3RdKTsKCgljb21wbGV0ZSgmbWNzcGlfZG1hLT5kbWFfcnhfY29tcGxldGlvbik7CgoJLyogV2UgbXVzdCBkaXNhYmxlIHRoZSBETUEgUlggcmVxdWVzdCAqLwoJb21hcDJfbWNzcGlfc2V0X2RtYV9yZXEoc3BpLCAxLCAwKTsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfZG1hX3R4X2NhbGxiYWNrKGludCBsY2gsIHUxNiBjaF9zdGF0dXMsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBzcGlfZGV2aWNlCSpzcGkgPSBkYXRhOwoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKm1jc3BpX2RtYTsKCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEoc3BpLT5tYXN0ZXIpOwoJbWNzcGlfZG1hID0gJihtY3NwaS0+ZG1hX2NoYW5uZWxzW3NwaS0+Y2hpcF9zZWxlY3RdKTsKCgljb21wbGV0ZSgmbWNzcGlfZG1hLT5kbWFfdHhfY29tcGxldGlvbik7CgoJLyogV2UgbXVzdCBkaXNhYmxlIHRoZSBETUEgVFggcmVxdWVzdCAqLwoJb21hcDJfbWNzcGlfc2V0X2RtYV9yZXEoc3BpLCAwLCAwKTsKfQoKc3RhdGljIGludCBvbWFwMl9tY3NwaV9yZXF1ZXN0X2RtYShzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpKQp7CglzdHJ1Y3Qgc3BpX21hc3RlcgkqbWFzdGVyID0gc3BpLT5tYXN0ZXI7CglzdHJ1Y3Qgb21hcDJfbWNzcGkJKm1jc3BpOwoJc3RydWN0IG9tYXAyX21jc3BpX2RtYQkqbWNzcGlfZG1hOwoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShtYXN0ZXIpOwoJbWNzcGlfZG1hID0gbWNzcGktPmRtYV9jaGFubmVscyArIHNwaS0+Y2hpcF9zZWxlY3Q7CgoJaWYgKG9tYXBfcmVxdWVzdF9kbWEobWNzcGlfZG1hLT5kbWFfcnhfc3luY19kZXYsICJNY1NQSSBSWCIsCgkJCW9tYXAyX21jc3BpX2RtYV9yeF9jYWxsYmFjaywgc3BpLAoJCQkmbWNzcGlfZG1hLT5kbWFfcnhfY2hhbm5lbCkpIHsKCQlkZXZfZXJyKCZzcGktPmRldiwgIm5vIFJYIERNQSBjaGFubmVsIGZvciBNY1NQSVxuIik7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJaWYgKG9tYXBfcmVxdWVzdF9kbWEobWNzcGlfZG1hLT5kbWFfdHhfc3luY19kZXYsICJNY1NQSSBUWCIsCgkJCW9tYXAyX21jc3BpX2RtYV90eF9jYWxsYmFjaywgc3BpLAoJCQkmbWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCkpIHsKCQlvbWFwX2ZyZWVfZG1hKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwpOwoJCW1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwgPSAtMTsKCQlkZXZfZXJyKCZzcGktPmRldiwgIm5vIFRYIERNQSBjaGFubmVsIGZvciBNY1NQSVxuIik7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJaW5pdF9jb21wbGV0aW9uKCZtY3NwaV9kbWEtPmRtYV9yeF9jb21wbGV0aW9uKTsKCWluaXRfY29tcGxldGlvbigmbWNzcGlfZG1hLT5kbWFfdHhfY29tcGxldGlvbik7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgb21hcDJfbWNzcGlfc2V0dXAoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKewoJaW50CQkJcmV0OwoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKm1jc3BpX2RtYTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9jcwkqY3MgPSBzcGktPmNvbnRyb2xsZXJfc3RhdGU7CgoJaWYgKHNwaS0+Yml0c19wZXJfd29yZCA8IDQgfHwgc3BpLT5iaXRzX3Blcl93b3JkID4gMzIpIHsKCQlkZXZfZGJnKCZzcGktPmRldiwgInNldHVwOiB1bnN1cHBvcnRlZCAlZCBiaXQgd29yZHNcbiIsCgkJCXNwaS0+Yml0c19wZXJfd29yZCk7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKHNwaS0+bWFzdGVyKTsKCW1jc3BpX2RtYSA9ICZtY3NwaS0+ZG1hX2NoYW5uZWxzW3NwaS0+Y2hpcF9zZWxlY3RdOwoKCWlmICghY3MpIHsKCQljcyA9IGt6YWxsb2Moc2l6ZW9mICpjcywgR0ZQX0tFUk5FTCk7CgkJaWYgKCFjcykKCQkJcmV0dXJuIC1FTk9NRU07CgkJY3MtPmJhc2UgPSBtY3NwaS0+YmFzZSArIHNwaS0+Y2hpcF9zZWxlY3QgKiAweDE0OwoJCWNzLT5waHlzID0gbWNzcGktPnBoeXMgKyBzcGktPmNoaXBfc2VsZWN0ICogMHgxNDsKCQljcy0+Y2hjb25mMCA9IDA7CgkJc3BpLT5jb250cm9sbGVyX3N0YXRlID0gY3M7CgkJLyogTGluayB0aGlzIHRvIGNvbnRleHQgc2F2ZSBsaXN0ICovCgkJbGlzdF9hZGRfdGFpbCgmY3MtPm5vZGUsCgkJCSZvbWFwMl9tY3NwaV9jdHhbbWNzcGktPm1hc3Rlci0+YnVzX251bSAtIDFdLmNzKTsKCX0KCglpZiAobWNzcGlfZG1hLT5kbWFfcnhfY2hhbm5lbCA9PSAtMQoJCQl8fCBtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsID09IC0xKSB7CgkJcmV0ID0gb21hcDJfbWNzcGlfcmVxdWVzdF9kbWEoc3BpKTsKCQlpZiAocmV0IDwgMCkKCQkJcmV0dXJuIHJldDsKCX0KCglpZiAob21hcDJfbWNzcGlfZW5hYmxlX2Nsb2NrcyhtY3NwaSkpCgkJcmV0dXJuIC1FTk9ERVY7CgoJcmV0ID0gb21hcDJfbWNzcGlfc2V0dXBfdHJhbnNmZXIoc3BpLCBOVUxMKTsKCW9tYXAyX21jc3BpX2Rpc2FibGVfY2xvY2tzKG1jc3BpKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBvbWFwMl9tY3NwaV9jbGVhbnVwKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfZG1hCSptY3NwaV9kbWE7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJKmNzOwoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShzcGktPm1hc3Rlcik7CgltY3NwaV9kbWEgPSAmbWNzcGktPmRtYV9jaGFubmVsc1tzcGktPmNoaXBfc2VsZWN0XTsKCglpZiAoc3BpLT5jb250cm9sbGVyX3N0YXRlKSB7CgkJLyogVW5saW5rIGNvbnRyb2xsZXIgc3RhdGUgZnJvbSBjb250ZXh0IHNhdmUgbGlzdCAqLwoJCWNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoJCWxpc3RfZGVsKCZjcy0+bm9kZSk7CgoJCWtmcmVlKHNwaS0+Y29udHJvbGxlcl9zdGF0ZSk7Cgl9CgoJaWYgKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwgIT0gLTEpIHsKCQlvbWFwX2ZyZWVfZG1hKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwpOwoJCW1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwgPSAtMTsKCX0KCWlmIChtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsICE9IC0xKSB7CgkJb21hcF9mcmVlX2RtYShtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsKTsKCQltY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsID0gLTE7Cgl9Cn0KCnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGkJKm1jc3BpOwoKCW1jc3BpID0gY29udGFpbmVyX29mKHdvcmssIHN0cnVjdCBvbWFwMl9tY3NwaSwgd29yayk7CglzcGluX2xvY2tfaXJxKCZtY3NwaS0+bG9jayk7CgoJaWYgKG9tYXAyX21jc3BpX2VuYWJsZV9jbG9ja3MobWNzcGkpKQoJCWdvdG8gb3V0OwoKCS8qIFdlIG9ubHkgZW5hYmxlIG9uZSBjaGFubmVsIGF0IGEgdGltZSAtLSB0aGUgb25lIHdob3NlIG1lc3NhZ2UgaXMKCSAqIGF0IHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSAtLSBhbHRob3VnaCB0aGlzIGNvbnRyb2xsZXIgd291bGQgZ2xhZGx5CgkgKiBhcmJpdHJhdGUgYW1vbmcgbXVsdGlwbGUgY2hhbm5lbHMuICBUaGlzIGNvcnJlc3BvbmRzIHRvICJzaW5nbGUKCSAqIGNoYW5uZWwiIG1hc3RlciBtb2RlLiAgQXMgYSBzaWRlIGVmZmVjdCwgd2UgbmVlZCB0byBtYW5hZ2UgdGhlCgkgKiBjaGlwc2VsZWN0IHdpdGggdGhlIEZPUkNFIGJpdCAuLi4gQ1MgIT0gY2hhbm5lbCBlbmFibGUuCgkgKi8KCXdoaWxlICghbGlzdF9lbXB0eSgmbWNzcGktPm1zZ19xdWV1ZSkpIHsKCQlzdHJ1Y3Qgc3BpX21lc3NhZ2UJCSptOwoJCXN0cnVjdCBzcGlfZGV2aWNlCQkqc3BpOwoJCXN0cnVjdCBzcGlfdHJhbnNmZXIJCSp0ID0gTlVMTDsKCQlpbnQJCQkJY3NfYWN0aXZlID0gMDsKCQlzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJCSpjczsKCQlpbnQJCQkJcGFyX292ZXJyaWRlID0gMDsKCQlpbnQJCQkJc3RhdHVzID0gMDsKCQl1MzIJCQkJY2hjb25mOwoKCQltID0gY29udGFpbmVyX29mKG1jc3BpLT5tc2dfcXVldWUubmV4dCwgc3RydWN0IHNwaV9tZXNzYWdlLAoJCQkJIHF1ZXVlKTsKCgkJbGlzdF9kZWxfaW5pdCgmbS0+cXVldWUpOwoJCXNwaW5fdW5sb2NrX2lycSgmbWNzcGktPmxvY2spOwoKCQlzcGkgPSBtLT5zcGk7CgkJY3MgPSBzcGktPmNvbnRyb2xsZXJfc3RhdGU7CgoJCW9tYXAyX21jc3BpX3NldF9lbmFibGUoc3BpLCAxKTsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHQsICZtLT50cmFuc2ZlcnMsIHRyYW5zZmVyX2xpc3QpIHsKCQkJaWYgKHQtPnR4X2J1ZiA9PSBOVUxMICYmIHQtPnJ4X2J1ZiA9PSBOVUxMICYmIHQtPmxlbikgewoJCQkJc3RhdHVzID0gLUVJTlZBTDsKCQkJCWJyZWFrOwoJCQl9CgkJCWlmIChwYXJfb3ZlcnJpZGUgfHwgdC0+c3BlZWRfaHogfHwgdC0+Yml0c19wZXJfd29yZCkgewoJCQkJcGFyX292ZXJyaWRlID0gMTsKCQkJCXN0YXR1cyA9IG9tYXAyX21jc3BpX3NldHVwX3RyYW5zZmVyKHNwaSwgdCk7CgkJCQlpZiAoc3RhdHVzIDwgMCkKCQkJCQlicmVhazsKCQkJCWlmICghdC0+c3BlZWRfaHogJiYgIXQtPmJpdHNfcGVyX3dvcmQpCgkJCQkJcGFyX292ZXJyaWRlID0gMDsKCQkJfQoKCQkJaWYgKCFjc19hY3RpdmUpIHsKCQkJCW9tYXAyX21jc3BpX2ZvcmNlX2NzKHNwaSwgMSk7CgkJCQljc19hY3RpdmUgPSAxOwoJCQl9CgoJCQljaGNvbmYgPSBtY3NwaV9jYWNoZWRfY2hjb25mMChzcGkpOwoJCQljaGNvbmYgJj0gfk9NQVAyX01DU1BJX0NIQ09ORl9UUk1fTUFTSzsKCQkJaWYgKHQtPnR4X2J1ZiA9PSBOVUxMKQoJCQkJY2hjb25mIHw9IE9NQVAyX01DU1BJX0NIQ09ORl9UUk1fUlhfT05MWTsKCQkJZWxzZSBpZiAodC0+cnhfYnVmID09IE5VTEwpCgkJCQljaGNvbmYgfD0gT01BUDJfTUNTUElfQ0hDT05GX1RSTV9UWF9PTkxZOwoJCQltY3NwaV93cml0ZV9jaGNvbmYwKHNwaSwgY2hjb25mKTsKCgkJCWlmICh0LT5sZW4pIHsKCQkJCXVuc2lnbmVkCWNvdW50OwoKCQkJCS8qIFJYX09OTFkgbW9kZSBuZWVkcyBkdW1teSBkYXRhIGluIFRYIHJlZyAqLwoJCQkJaWYgKHQtPnR4X2J1ZiA9PSBOVUxMKQoJCQkJCV9fcmF3X3dyaXRlbCgwLCBjcy0+YmFzZQoJCQkJCQkJKyBPTUFQMl9NQ1NQSV9UWDApOwoKCQkJCWlmIChtLT5pc19kbWFfbWFwcGVkIHx8IHQtPmxlbiA+PSBETUFfTUlOX0JZVEVTKQoJCQkJCWNvdW50ID0gb21hcDJfbWNzcGlfdHhyeF9kbWEoc3BpLCB0KTsKCQkJCWVsc2UKCQkJCQljb3VudCA9IG9tYXAyX21jc3BpX3R4cnhfcGlvKHNwaSwgdCk7CgkJCQltLT5hY3R1YWxfbGVuZ3RoICs9IGNvdW50OwoKCQkJCWlmIChjb3VudCAhPSB0LT5sZW4pIHsKCQkJCQlzdGF0dXMgPSAtRUlPOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlpZiAodC0+ZGVsYXlfdXNlY3MpCgkJCQl1ZGVsYXkodC0+ZGVsYXlfdXNlY3MpOwoKCQkJLyogaWdub3JlIHRoZSAibGVhdmUgaXQgb24gYWZ0ZXIgbGFzdCB4ZmVyIiBoaW50ICovCgkJCWlmICh0LT5jc19jaGFuZ2UpIHsKCQkJCW9tYXAyX21jc3BpX2ZvcmNlX2NzKHNwaSwgMCk7CgkJCQljc19hY3RpdmUgPSAwOwoJCQl9CgkJfQoKCQkvKiBSZXN0b3JlIGRlZmF1bHRzIGlmIHRoZXkgd2VyZSBvdmVycmlkZW4gKi8KCQlpZiAocGFyX292ZXJyaWRlKSB7CgkJCXBhcl9vdmVycmlkZSA9IDA7CgkJCXN0YXR1cyA9IG9tYXAyX21jc3BpX3NldHVwX3RyYW5zZmVyKHNwaSwgTlVMTCk7CgkJfQoKCQlpZiAoY3NfYWN0aXZlKQoJCQlvbWFwMl9tY3NwaV9mb3JjZV9jcyhzcGksIDApOwoKCQlvbWFwMl9tY3NwaV9zZXRfZW5hYmxlKHNwaSwgMCk7CgoJCW0tPnN0YXR1cyA9IHN0YXR1czsKCQltLT5jb21wbGV0ZShtLT5jb250ZXh0KTsKCgkJc3Bpbl9sb2NrX2lycSgmbWNzcGktPmxvY2spOwoJfQoKCW9tYXAyX21jc3BpX2Rpc2FibGVfY2xvY2tzKG1jc3BpKTsKCm91dDoKCXNwaW5fdW5sb2NrX2lycSgmbWNzcGktPmxvY2spOwp9CgpzdGF0aWMgaW50IG9tYXAyX21jc3BpX3RyYW5zZmVyKHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIHN0cnVjdCBzcGlfbWVzc2FnZSAqbSkKewoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXVuc2lnbmVkIGxvbmcJCWZsYWdzOwoJc3RydWN0IHNwaV90cmFuc2ZlcgkqdDsKCgltLT5hY3R1YWxfbGVuZ3RoID0gMDsKCW0tPnN0YXR1cyA9IDA7CgoJLyogcmVqZWN0IGludmFsaWQgbWVzc2FnZXMgYW5kIHRyYW5zZmVycyAqLwoJaWYgKGxpc3RfZW1wdHkoJm0tPnRyYW5zZmVycykgfHwgIW0tPmNvbXBsZXRlKQoJCXJldHVybiAtRUlOVkFMOwoJbGlzdF9mb3JfZWFjaF9lbnRyeSh0LCAmbS0+dHJhbnNmZXJzLCB0cmFuc2Zlcl9saXN0KSB7CgkJY29uc3Qgdm9pZAkqdHhfYnVmID0gdC0+dHhfYnVmOwoJCXZvaWQJCSpyeF9idWYgPSB0LT5yeF9idWY7CgkJdW5zaWduZWQJbGVuID0gdC0+bGVuOwoKCQlpZiAodC0+c3BlZWRfaHogPiBPTUFQMl9NQ1NQSV9NQVhfRlJFUQoJCQkJfHwgKGxlbiAmJiAhKHJ4X2J1ZiB8fCB0eF9idWYpKQoJCQkJfHwgKHQtPmJpdHNfcGVyX3dvcmQgJiYKCQkJCQkoICB0LT5iaXRzX3Blcl93b3JkIDwgNAoJCQkJCXx8IHQtPmJpdHNfcGVyX3dvcmQgPiAzMikpKSB7CgkJCWRldl9kYmcoJnNwaS0+ZGV2LCAidHJhbnNmZXI6ICVkIEh6LCAlZCAlcyVzLCAlZCBicHdcbiIsCgkJCQkJdC0+c3BlZWRfaHosCgkJCQkJbGVuLAoJCQkJCXR4X2J1ZiA/ICJ0eCIgOiAiIiwKCQkJCQlyeF9idWYgPyAicngiIDogIiIsCgkJCQkJdC0+Yml0c19wZXJfd29yZCk7CgkJCXJldHVybiAtRUlOVkFMOwoJCX0KCQlpZiAodC0+c3BlZWRfaHogJiYgdC0+c3BlZWRfaHogPCBPTUFQMl9NQ1NQSV9NQVhfRlJFUS8oMTw8MTYpKSB7CgkJCWRldl9kYmcoJnNwaS0+ZGV2LCAiJWQgSHogbWF4IGV4Y2VlZHMgJWRcbiIsCgkJCQkJdC0+c3BlZWRfaHosCgkJCQkJT01BUDJfTUNTUElfTUFYX0ZSRVEvKDE8PDE2KSk7CgkJCXJldHVybiAtRUlOVkFMOwoJCX0KCgkJaWYgKG0tPmlzX2RtYV9tYXBwZWQgfHwgbGVuIDwgRE1BX01JTl9CWVRFUykKCQkJY29udGludWU7CgoJCS8qIERvIERNQSBtYXBwaW5nICJlYXJseSIgZm9yIGJldHRlciBlcnJvciByZXBvcnRpbmcgYW5kCgkJICogZGNhY2hlIHVzZS4gIE5vdGUgdGhhdCBpZiBkbWFfdW5tYXBfc2luZ2xlKCkgZXZlciBzdGFydHMKCQkgKiB0byBkbyByZWFsIHdvcmsgb24gQVJNLCB3ZSdkIG5lZWQgdG8gY2xlYW4gdXAgbWFwcGluZ3MKCQkgKiBmb3IgcHJldmlvdXMgdHJhbnNmZXJzIG9uICpBTEwqIGV4aXRzIG9mIHRoaXMgbG9vcC4uLgoJCSAqLwoJCWlmICh0eF9idWYgIT0gTlVMTCkgewoJCQl0LT50eF9kbWEgPSBkbWFfbWFwX3NpbmdsZSgmc3BpLT5kZXYsICh2b2lkICopIHR4X2J1ZiwKCQkJCQlsZW4sIERNQV9UT19ERVZJQ0UpOwoJCQlpZiAoZG1hX21hcHBpbmdfZXJyb3IoJnNwaS0+ZGV2LCB0LT50eF9kbWEpKSB7CgkJCQlkZXZfZGJnKCZzcGktPmRldiwgImRtYSAlY1ggJWQgYnl0ZXMgZXJyb3JcbiIsCgkJCQkJCSdUJywgbGVuKTsKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl9CgkJfQoJCWlmIChyeF9idWYgIT0gTlVMTCkgewoJCQl0LT5yeF9kbWEgPSBkbWFfbWFwX3NpbmdsZSgmc3BpLT5kZXYsIHJ4X2J1ZiwgdC0+bGVuLAoJCQkJCURNQV9GUk9NX0RFVklDRSk7CgkJCWlmIChkbWFfbWFwcGluZ19lcnJvcigmc3BpLT5kZXYsIHQtPnJ4X2RtYSkpIHsKCQkJCWRldl9kYmcoJnNwaS0+ZGV2LCAiZG1hICVjWCAlZCBieXRlcyBlcnJvclxuIiwKCQkJCQkJJ1InLCBsZW4pOwoJCQkJaWYgKHR4X2J1ZiAhPSBOVUxMKQoJCQkJCWRtYV91bm1hcF9zaW5nbGUoTlVMTCwgdC0+dHhfZG1hLAoJCQkJCQkJbGVuLCBETUFfVE9fREVWSUNFKTsKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl9CgkJfQoJfQoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShzcGktPm1hc3Rlcik7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJm1jc3BpLT5sb2NrLCBmbGFncyk7CglsaXN0X2FkZF90YWlsKCZtLT5xdWV1ZSwgJm1jc3BpLT5tc2dfcXVldWUpOwoJcXVldWVfd29yayhvbWFwMl9tY3NwaV93cSwgJm1jc3BpLT53b3JrKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm1jc3BpLT5sb2NrLCBmbGFncyk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgX19pbml0IG9tYXAyX21jc3BpX3Jlc2V0KHN0cnVjdCBvbWFwMl9tY3NwaSAqbWNzcGkpCnsKCXN0cnVjdCBzcGlfbWFzdGVyCSptYXN0ZXIgPSBtY3NwaS0+bWFzdGVyOwoJdTMyCQkJdG1wOwoKCWlmIChvbWFwMl9tY3NwaV9lbmFibGVfY2xvY2tzKG1jc3BpKSkKCQlyZXR1cm4gLTE7CgoJbWNzcGlfd3JpdGVfcmVnKG1hc3RlciwgT01BUDJfTUNTUElfU1lTQ09ORklHLAoJCQlPTUFQMl9NQ1NQSV9TWVNDT05GSUdfU09GVFJFU0VUKTsKCWRvIHsKCQl0bXAgPSBtY3NwaV9yZWFkX3JlZyhtYXN0ZXIsIE9NQVAyX01DU1BJX1NZU1NUQVRVUyk7Cgl9IHdoaWxlICghKHRtcCAmIE9NQVAyX01DU1BJX1NZU1NUQVRVU19SRVNFVERPTkUpKTsKCgl0bXAgPSBPTUFQMl9NQ1NQSV9TWVNDT05GSUdfQVVUT0lETEUgfAoJCU9NQVAyX01DU1BJX1NZU0NPTkZJR19FTkFXQUtFVVAgfAoJCU9NQVAyX01DU1BJX1NZU0NPTkZJR19TTUFSVElETEU7CgltY3NwaV93cml0ZV9yZWcobWFzdGVyLCBPTUFQMl9NQ1NQSV9TWVNDT05GSUcsIHRtcCk7CglvbWFwMl9tY3NwaV9jdHhbbWFzdGVyLT5idXNfbnVtIC0gMV0uc3lzY29uZmlnID0gdG1wOwoKCXRtcCA9IE9NQVAyX01DU1BJX1dBS0VVUEVOQUJMRV9XS0VOOwoJbWNzcGlfd3JpdGVfcmVnKG1hc3RlciwgT01BUDJfTUNTUElfV0FLRVVQRU5BQkxFLCB0bXApOwoJb21hcDJfbWNzcGlfY3R4W21hc3Rlci0+YnVzX251bSAtIDFdLndha2V1cGVuYWJsZSA9IHRtcDsKCglvbWFwMl9tY3NwaV9zZXRfbWFzdGVyX21vZGUobWFzdGVyKTsKCW9tYXAyX21jc3BpX2Rpc2FibGVfY2xvY2tzKG1jc3BpKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGkxX3J4ZG1hX2lkIFtdID0gewoJT01BUDI0WFhfRE1BX1NQSTFfUlgwLAoJT01BUDI0WFhfRE1BX1NQSTFfUlgxLAoJT01BUDI0WFhfRE1BX1NQSTFfUlgyLAoJT01BUDI0WFhfRE1BX1NQSTFfUlgzLAp9OwoKc3RhdGljIHU4IF9faW5pdGRhdGEgc3BpMV90eGRtYV9pZCBbXSA9IHsKCU9NQVAyNFhYX0RNQV9TUEkxX1RYMCwKCU9NQVAyNFhYX0RNQV9TUEkxX1RYMSwKCU9NQVAyNFhYX0RNQV9TUEkxX1RYMiwKCU9NQVAyNFhYX0RNQV9TUEkxX1RYMywKfTsKCnN0YXRpYyB1OCBfX2luaXRkYXRhIHNwaTJfcnhkbWFfaWRbXSA9IHsKCU9NQVAyNFhYX0RNQV9TUEkyX1JYMCwKCU9NQVAyNFhYX0RNQV9TUEkyX1JYMSwKfTsKCnN0YXRpYyB1OCBfX2luaXRkYXRhIHNwaTJfdHhkbWFfaWRbXSA9IHsKCU9NQVAyNFhYX0RNQV9TUEkyX1RYMCwKCU9NQVAyNFhYX0RNQV9TUEkyX1RYMSwKfTsKCiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAyNDMwKSB8fCBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAzKSBcCgl8fCBkZWZpbmVkKENPTkZJR19BUkNIX09NQVA0KQpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGkzX3J4ZG1hX2lkW10gPSB7CglPTUFQMjRYWF9ETUFfU1BJM19SWDAsCglPTUFQMjRYWF9ETUFfU1BJM19SWDEsCn07CgpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGkzX3R4ZG1hX2lkW10gPSB7CglPTUFQMjRYWF9ETUFfU1BJM19UWDAsCglPTUFQMjRYWF9ETUFfU1BJM19UWDEsCn07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDMpIHx8IGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDQpCnN0YXRpYyB1OCBfX2luaXRkYXRhIHNwaTRfcnhkbWFfaWRbXSA9IHsKCU9NQVAzNFhYX0RNQV9TUEk0X1JYMCwKfTsKCnN0YXRpYyB1OCBfX2luaXRkYXRhIHNwaTRfdHhkbWFfaWRbXSA9IHsKCU9NQVAzNFhYX0RNQV9TUEk0X1RYMCwKfTsKI2VuZGlmCgpzdGF0aWMgaW50IF9faW5pdCBvbWFwMl9tY3NwaV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglzdHJ1Y3Qgc3BpX21hc3RlcgkqbWFzdGVyOwoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXN0cnVjdCByZXNvdXJjZQkJKnI7CglpbnQJCQlzdGF0dXMgPSAwLCBpOwoJY29uc3QgdTgJCSpyeGRtYV9pZCwgKnR4ZG1hX2lkOwoJdW5zaWduZWQJCW51bV9jaGlwc2VsZWN0OwoKCXN3aXRjaCAocGRldi0+aWQpIHsKCWNhc2UgMToKCQlyeGRtYV9pZCA9IHNwaTFfcnhkbWFfaWQ7CgkJdHhkbWFfaWQgPSBzcGkxX3R4ZG1hX2lkOwoJCW51bV9jaGlwc2VsZWN0ID0gNDsKCQlicmVhazsKCWNhc2UgMjoKCQlyeGRtYV9pZCA9IHNwaTJfcnhkbWFfaWQ7CgkJdHhkbWFfaWQgPSBzcGkyX3R4ZG1hX2lkOwoJCW51bV9jaGlwc2VsZWN0ID0gMjsKCQlicmVhazsKI2lmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDI0MzApIHx8IGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDMpIFwKCXx8IGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDQpCgljYXNlIDM6CgkJcnhkbWFfaWQgPSBzcGkzX3J4ZG1hX2lkOwoJCXR4ZG1hX2lkID0gc3BpM190eGRtYV9pZDsKCQludW1fY2hpcHNlbGVjdCA9IDI7CgkJYnJlYWs7CiNlbmRpZgojaWYgZGVmaW5lZChDT05GSUdfQVJDSF9PTUFQMykgfHwgZGVmaW5lZChDT05GSUdfQVJDSF9PTUFQNCkKCWNhc2UgNDoKCQlyeGRtYV9pZCA9IHNwaTRfcnhkbWFfaWQ7CgkJdHhkbWFfaWQgPSBzcGk0X3R4ZG1hX2lkOwoJCW51bV9jaGlwc2VsZWN0ID0gMTsKCQlicmVhazsKI2VuZGlmCglkZWZhdWx0OgoJCXJldHVybiAtRUlOVkFMOwoJfQoKCW1hc3RlciA9IHNwaV9hbGxvY19tYXN0ZXIoJnBkZXYtPmRldiwgc2l6ZW9mICptY3NwaSk7CglpZiAobWFzdGVyID09IE5VTEwpIHsKCQlkZXZfZGJnKCZwZGV2LT5kZXYsICJtYXN0ZXIgYWxsb2NhdGlvbiBmYWlsZWRcbiIpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCS8qIHRoZSBzcGktPm1vZGUgYml0cyB1bmRlcnN0b29kIGJ5IHRoaXMgZHJpdmVyOiAqLwoJbWFzdGVyLT5tb2RlX2JpdHMgPSBTUElfQ1BPTCB8IFNQSV9DUEhBIHwgU1BJX0NTX0hJR0g7CgoJaWYgKHBkZXYtPmlkICE9IC0xKQoJCW1hc3Rlci0+YnVzX251bSA9IHBkZXYtPmlkOwoKCW1hc3Rlci0+c2V0dXAgPSBvbWFwMl9tY3NwaV9zZXR1cDsKCW1hc3Rlci0+dHJhbnNmZXIgPSBvbWFwMl9tY3NwaV90cmFuc2ZlcjsKCW1hc3Rlci0+Y2xlYW51cCA9IG9tYXAyX21jc3BpX2NsZWFudXA7CgltYXN0ZXItPm51bV9jaGlwc2VsZWN0ID0gbnVtX2NoaXBzZWxlY3Q7CgoJZGV2X3NldF9kcnZkYXRhKCZwZGV2LT5kZXYsIG1hc3Rlcik7CgoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKG1hc3Rlcik7CgltY3NwaS0+bWFzdGVyID0gbWFzdGVyOwoKCXIgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwoJaWYgKHIgPT0gTlVMTCkgewoJCXN0YXR1cyA9IC1FTk9ERVY7CgkJZ290byBlcnIxOwoJfQoJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24oci0+c3RhcnQsIChyLT5lbmQgLSByLT5zdGFydCkgKyAxLAoJCQlkZXZfbmFtZSgmcGRldi0+ZGV2KSkpIHsKCQlzdGF0dXMgPSAtRUJVU1k7CgkJZ290byBlcnIxOwoJfQoKCW1jc3BpLT5waHlzID0gci0+c3RhcnQ7CgltY3NwaS0+YmFzZSA9IGlvcmVtYXAoci0+c3RhcnQsIHItPmVuZCAtIHItPnN0YXJ0ICsgMSk7CglpZiAoIW1jc3BpLT5iYXNlKSB7CgkJZGV2X2RiZygmcGRldi0+ZGV2LCAiY2FuJ3QgaW9yZW1hcCBNQ1NQSVxuIik7CgkJc3RhdHVzID0gLUVOT01FTTsKCQlnb3RvIGVycjFhYTsKCX0KCglJTklUX1dPUksoJm1jc3BpLT53b3JrLCBvbWFwMl9tY3NwaV93b3JrKTsKCglzcGluX2xvY2tfaW5pdCgmbWNzcGktPmxvY2spOwoJSU5JVF9MSVNUX0hFQUQoJm1jc3BpLT5tc2dfcXVldWUpOwoJSU5JVF9MSVNUX0hFQUQoJm9tYXAyX21jc3BpX2N0eFttYXN0ZXItPmJ1c19udW0gLSAxXS5jcyk7CgoJbWNzcGktPmljayA9IGNsa19nZXQoJnBkZXYtPmRldiwgImljayIpOwoJaWYgKElTX0VSUihtY3NwaS0+aWNrKSkgewoJCWRldl9kYmcoJnBkZXYtPmRldiwgImNhbid0IGdldCBtY3NwaV9pY2tcbiIpOwoJCXN0YXR1cyA9IFBUUl9FUlIobWNzcGktPmljayk7CgkJZ290byBlcnIxYTsKCX0KCW1jc3BpLT5mY2sgPSBjbGtfZ2V0KCZwZGV2LT5kZXYsICJmY2siKTsKCWlmIChJU19FUlIobWNzcGktPmZjaykpIHsKCQlkZXZfZGJnKCZwZGV2LT5kZXYsICJjYW4ndCBnZXQgbWNzcGlfZmNrXG4iKTsKCQlzdGF0dXMgPSBQVFJfRVJSKG1jc3BpLT5mY2spOwoJCWdvdG8gZXJyMjsKCX0KCgltY3NwaS0+ZG1hX2NoYW5uZWxzID0ga2NhbGxvYyhtYXN0ZXItPm51bV9jaGlwc2VsZWN0LAoJCQlzaXplb2Yoc3RydWN0IG9tYXAyX21jc3BpX2RtYSksCgkJCUdGUF9LRVJORUwpOwoKCWlmIChtY3NwaS0+ZG1hX2NoYW5uZWxzID09IE5VTEwpCgkJZ290byBlcnIzOwoKCWZvciAoaSA9IDA7IGkgPCBudW1fY2hpcHNlbGVjdDsgaSsrKSB7CgkJbWNzcGktPmRtYV9jaGFubmVsc1tpXS5kbWFfcnhfY2hhbm5lbCA9IC0xOwoJCW1jc3BpLT5kbWFfY2hhbm5lbHNbaV0uZG1hX3J4X3N5bmNfZGV2ID0gcnhkbWFfaWRbaV07CgkJbWNzcGktPmRtYV9jaGFubmVsc1tpXS5kbWFfdHhfY2hhbm5lbCA9IC0xOwoJCW1jc3BpLT5kbWFfY2hhbm5lbHNbaV0uZG1hX3R4X3N5bmNfZGV2ID0gdHhkbWFfaWRbaV07Cgl9CgoJaWYgKG9tYXAyX21jc3BpX3Jlc2V0KG1jc3BpKSA8IDApCgkJZ290byBlcnI0OwoKCXN0YXR1cyA9IHNwaV9yZWdpc3Rlcl9tYXN0ZXIobWFzdGVyKTsKCWlmIChzdGF0dXMgPCAwKQoJCWdvdG8gZXJyNDsKCglyZXR1cm4gc3RhdHVzOwoKZXJyNDoKCWtmcmVlKG1jc3BpLT5kbWFfY2hhbm5lbHMpOwplcnIzOgoJY2xrX3B1dChtY3NwaS0+ZmNrKTsKZXJyMjoKCWNsa19wdXQobWNzcGktPmljayk7CmVycjFhOgoJaW91bm1hcChtY3NwaS0+YmFzZSk7CmVycjFhYToKCXJlbGVhc2VfbWVtX3JlZ2lvbihyLT5zdGFydCwgKHItPmVuZCAtIHItPnN0YXJ0KSArIDEpOwplcnIxOgoJc3BpX21hc3Rlcl9wdXQobWFzdGVyKTsKCXJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyBpbnQgX19leGl0IG9tYXAyX21jc3BpX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglzdHJ1Y3Qgc3BpX21hc3RlcgkqbWFzdGVyOwoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKmRtYV9jaGFubmVsczsKCXN0cnVjdCByZXNvdXJjZQkJKnI7Cgl2b2lkIF9faW9tZW0gKmJhc2U7CgoJbWFzdGVyID0gZGV2X2dldF9kcnZkYXRhKCZwZGV2LT5kZXYpOwoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKG1hc3Rlcik7CglkbWFfY2hhbm5lbHMgPSBtY3NwaS0+ZG1hX2NoYW5uZWxzOwoKCWNsa19wdXQobWNzcGktPmZjayk7CgljbGtfcHV0KG1jc3BpLT5pY2spOwoKCXIgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwoJcmVsZWFzZV9tZW1fcmVnaW9uKHItPnN0YXJ0LCAoci0+ZW5kIC0gci0+c3RhcnQpICsgMSk7CgoJYmFzZSA9IG1jc3BpLT5iYXNlOwoJc3BpX3VucmVnaXN0ZXJfbWFzdGVyKG1hc3Rlcik7Cglpb3VubWFwKGJhc2UpOwoJa2ZyZWUoZG1hX2NoYW5uZWxzKTsKCglyZXR1cm4gMDsKfQoKLyogd29yayB3aXRoIGhvdHBsdWcgYW5kIGNvbGRwbHVnICovCk1PRFVMRV9BTElBUygicGxhdGZvcm06b21hcDJfbWNzcGkiKTsKCnN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG9tYXAyX21jc3BpX2RyaXZlciA9IHsKCS5kcml2ZXIgPSB7CgkJLm5hbWUgPQkJIm9tYXAyX21jc3BpIiwKCQkub3duZXIgPQlUSElTX01PRFVMRSwKCX0sCgkucmVtb3ZlID0JX19leGl0X3Aob21hcDJfbWNzcGlfcmVtb3ZlKSwKfTsKCgpzdGF0aWMgaW50IF9faW5pdCBvbWFwMl9tY3NwaV9pbml0KHZvaWQpCnsKCW9tYXAyX21jc3BpX3dxID0gY3JlYXRlX3NpbmdsZXRocmVhZF93b3JrcXVldWUoCgkJCQlvbWFwMl9tY3NwaV9kcml2ZXIuZHJpdmVyLm5hbWUpOwoJaWYgKG9tYXAyX21jc3BpX3dxID09IE5VTEwpCgkJcmV0dXJuIC0xOwoJcmV0dXJuIHBsYXRmb3JtX2RyaXZlcl9wcm9iZSgmb21hcDJfbWNzcGlfZHJpdmVyLCBvbWFwMl9tY3NwaV9wcm9iZSk7Cn0Kc3Vic3lzX2luaXRjYWxsKG9tYXAyX21jc3BpX2luaXQpOwoKc3RhdGljIHZvaWQgX19leGl0IG9tYXAyX21jc3BpX2V4aXQodm9pZCkKewoJcGxhdGZvcm1fZHJpdmVyX3VucmVnaXN0ZXIoJm9tYXAyX21jc3BpX2RyaXZlcik7CgoJZGVzdHJveV93b3JrcXVldWUob21hcDJfbWNzcGlfd3EpOwp9Cm1vZHVsZV9leGl0KG9tYXAyX21jc3BpX2V4aXQpOwoKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=