LyoKICogT01BUDIgTWNTUEkgY29udHJvbGxlciBkcml2ZXIKICoKICogQ29weXJpZ2h0IChDKSAyMDA1LCAyMDA2IE5va2lhIENvcnBvcmF0aW9uCiAqIEF1dGhvcjoJU2FtdWVsIE9ydGl6IDxzYW11ZWwub3J0aXpAbm9raWEuY29tPiBhbmQKICoJCUp1aGEgWXJq9mzkIDxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICoKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgojaW5jbHVkZSA8bGludXgvZXJyLmg+CiNpbmNsdWRlIDxsaW51eC9jbGsuaD4KI2luY2x1ZGUgPGxpbnV4L2lvLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CgojaW5jbHVkZSA8bGludXgvc3BpL3NwaS5oPgoKI2luY2x1ZGUgPHBsYXQvZG1hLmg+CiNpbmNsdWRlIDxwbGF0L2Nsb2NrLmg+CgoKI2RlZmluZSBPTUFQMl9NQ1NQSV9NQVhfRlJFUQkJNDgwMDAwMDAKCi8qIE9NQVAyIGhhcyAzIFNQSSBjb250cm9sbGVycywgd2hpbGUgT01BUDMgaGFzIDQgKi8KI2RlZmluZSBPTUFQMl9NQ1NQSV9NQVhfQ1RSTCAJCTQKCiNkZWZpbmUgT01BUDJfTUNTUElfUkVWSVNJT04JCTB4MDAKI2RlZmluZSBPTUFQMl9NQ1NQSV9TWVNDT05GSUcJCTB4MTAKI2RlZmluZSBPTUFQMl9NQ1NQSV9TWVNTVEFUVVMJCTB4MTQKI2RlZmluZSBPTUFQMl9NQ1NQSV9JUlFTVEFUVVMJCTB4MTgKI2RlZmluZSBPTUFQMl9NQ1NQSV9JUlFFTkFCTEUJCTB4MWMKI2RlZmluZSBPTUFQMl9NQ1NQSV9XQUtFVVBFTkFCTEUJMHgyMAojZGVmaW5lIE9NQVAyX01DU1BJX1NZU1QJCTB4MjQKI2RlZmluZSBPTUFQMl9NQ1NQSV9NT0RVTENUUkwJCTB4MjgKCi8qIHBlci1jaGFubmVsIGJhbmtzLCAweDE0IGJ5dGVzIGVhY2gsIGZpcnN0IGlzOiAqLwojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORjAJCTB4MmMKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSFNUQVQwCQkweDMwCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDVFJMMAkJMHgzNAojZGVmaW5lIE9NQVAyX01DU1BJX1RYMAkJCTB4MzgKI2RlZmluZSBPTUFQMl9NQ1NQSV9SWDAJCQkweDNjCgovKiBwZXItcmVnaXN0ZXIgYml0bWFza3M6ICovCgojZGVmaW5lIE9NQVAyX01DU1BJX1NZU0NPTkZJR19TTUFSVElETEUJQklUKDQpCiNkZWZpbmUgT01BUDJfTUNTUElfU1lTQ09ORklHX0VOQVdBS0VVUAlCSVQoMikKI2RlZmluZSBPTUFQMl9NQ1NQSV9TWVNDT05GSUdfQVVUT0lETEUJQklUKDApCiNkZWZpbmUgT01BUDJfTUNTUElfU1lTQ09ORklHX1NPRlRSRVNFVAlCSVQoMSkKCiNkZWZpbmUgT01BUDJfTUNTUElfU1lTU1RBVFVTX1JFU0VURE9ORQlCSVQoMCkKCiNkZWZpbmUgT01BUDJfTUNTUElfTU9EVUxDVFJMX1NJTkdMRQlCSVQoMCkKI2RlZmluZSBPTUFQMl9NQ1NQSV9NT0RVTENUUkxfTVMJQklUKDIpCiNkZWZpbmUgT01BUDJfTUNTUElfTU9EVUxDVFJMX1NURVNUCUJJVCgzKQoKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfUEhBCQlCSVQoMCkKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfUE9MCQlCSVQoMSkKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfQ0xLRF9NQVNLCSgweDBmIDw8IDIpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX0VQT0wJCUJJVCg2KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9XTF9NQVNLCSgweDFmIDw8IDcpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX1RSTV9SWF9PTkxZCUJJVCgxMikKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfVFJNX1RYX09OTFkJQklUKDEzKQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9UUk1fTUFTSwkoMHgwMyA8PCAxMikKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfRE1BVwkJQklUKDE0KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9ETUFSCQlCSVQoMTUpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX0RQRTAJCUJJVCgxNikKI2RlZmluZSBPTUFQMl9NQ1NQSV9DSENPTkZfRFBFMQkJQklUKDE3KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9JUwkJQklUKDE4KQojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ09ORl9UVVJCTwlCSVQoMTkpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hDT05GX0ZPUkNFCUJJVCgyMCkKCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hTVEFUX1JYUwkJQklUKDApCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hTVEFUX1RYUwkJQklUKDEpCiNkZWZpbmUgT01BUDJfTUNTUElfQ0hTVEFUX0VPVAkJQklUKDIpCgojZGVmaW5lIE9NQVAyX01DU1BJX0NIQ1RSTF9FTgkJQklUKDApCgojZGVmaW5lIE9NQVAyX01DU1BJX1dBS0VVUEVOQUJMRV9XS0VOCUJJVCgwKQoKLyogV2UgaGF2ZSAyIERNQSBjaGFubmVscyBwZXIgQ1MsIG9uZSBmb3IgUlggYW5kIG9uZSBmb3IgVFggKi8Kc3RydWN0IG9tYXAyX21jc3BpX2RtYSB7CglpbnQgZG1hX3R4X2NoYW5uZWw7CglpbnQgZG1hX3J4X2NoYW5uZWw7CgoJaW50IGRtYV90eF9zeW5jX2RldjsKCWludCBkbWFfcnhfc3luY19kZXY7CgoJc3RydWN0IGNvbXBsZXRpb24gZG1hX3R4X2NvbXBsZXRpb247CglzdHJ1Y3QgY29tcGxldGlvbiBkbWFfcnhfY29tcGxldGlvbjsKfTsKCi8qIHVzZSBQSU8gZm9yIHNtYWxsIHRyYW5zZmVycywgYXZvaWRpbmcgRE1BIHNldHVwL3RlYXJkb3duIG92ZXJoZWFkIGFuZAogKiBjYWNoZSBvcGVyYXRpb25zOyBiZXR0ZXIgaGV1cmlzdGljcyBjb25zaWRlciB3b3Jkc2l6ZSBhbmQgYml0cmF0ZS4KICovCiNkZWZpbmUgRE1BX01JTl9CWVRFUwkJCTgKCgpzdHJ1Y3Qgb21hcDJfbWNzcGkgewoJc3RydWN0IHdvcmtfc3RydWN0CXdvcms7CgkvKiBsb2NrIHByb3RlY3RzIHF1ZXVlIGFuZCByZWdpc3RlcnMgKi8KCXNwaW5sb2NrX3QJCWxvY2s7CglzdHJ1Y3QgbGlzdF9oZWFkCW1zZ19xdWV1ZTsKCXN0cnVjdCBzcGlfbWFzdGVyCSptYXN0ZXI7CglzdHJ1Y3QgY2xrCQkqaWNrOwoJc3RydWN0IGNsawkJKmZjazsKCS8qIFZpcnR1YWwgYmFzZSBhZGRyZXNzIG9mIHRoZSBjb250cm9sbGVyICovCgl2b2lkIF9faW9tZW0JCSpiYXNlOwoJdW5zaWduZWQgbG9uZwkJcGh5czsKCS8qIFNQSTEgaGFzIDQgY2hhbm5lbHMsIHdoaWxlIFNQSTIgaGFzIDIgKi8KCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKmRtYV9jaGFubmVsczsKfTsKCnN0cnVjdCBvbWFwMl9tY3NwaV9jcyB7Cgl2b2lkIF9faW9tZW0JCSpiYXNlOwoJdW5zaWduZWQgbG9uZwkJcGh5czsKCWludAkJCXdvcmRfbGVuOwoJc3RydWN0IGxpc3RfaGVhZAlub2RlOwoJLyogQ29udGV4dCBzYXZlIGFuZCByZXN0b3JlIHNoYWRvdyByZWdpc3RlciAqLwoJdTMyCQkJY2hjb25mMDsKfTsKCi8qIHVzZWQgZm9yIGNvbnRleHQgc2F2ZSBhbmQgcmVzdG9yZSwgc3RydWN0dXJlIG1lbWJlcnMgdG8gYmUgdXBkYXRlZCB3aGVuZXZlcgogKiBjb3JyZXNwb25kaW5nIHJlZ2lzdGVycyBhcmUgbW9kaWZpZWQuCiAqLwpzdHJ1Y3Qgb21hcDJfbWNzcGlfcmVncyB7Cgl1MzIgc3lzY29uZmlnOwoJdTMyIG1vZHVsY3RybDsKCXUzMiB3YWtldXBlbmFibGU7CglzdHJ1Y3QgbGlzdF9oZWFkIGNzOwp9OwoKc3RhdGljIHN0cnVjdCBvbWFwMl9tY3NwaV9yZWdzIG9tYXAyX21jc3BpX2N0eFtPTUFQMl9NQ1NQSV9NQVhfQ1RSTF07CgpzdGF0aWMgc3RydWN0IHdvcmtxdWV1ZV9zdHJ1Y3QgKm9tYXAyX21jc3BpX3dxOwoKI2RlZmluZSBNT0RfUkVHX0JJVCh2YWwsIG1hc2ssIHNldCkgZG8geyBcCglpZiAoc2V0KSBcCgkJdmFsIHw9IG1hc2s7IFwKCWVsc2UgXAoJCXZhbCAmPSB+bWFzazsgXAp9IHdoaWxlICgwKQoKc3RhdGljIGlubGluZSB2b2lkIG1jc3BpX3dyaXRlX3JlZyhzdHJ1Y3Qgc3BpX21hc3RlciAqbWFzdGVyLAoJCWludCBpZHgsIHUzMiB2YWwpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaSAqbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKG1hc3Rlcik7CgoJX19yYXdfd3JpdGVsKHZhbCwgbWNzcGktPmJhc2UgKyBpZHgpOwp9CgpzdGF0aWMgaW5saW5lIHUzMiBtY3NwaV9yZWFkX3JlZyhzdHJ1Y3Qgc3BpX21hc3RlciAqbWFzdGVyLCBpbnQgaWR4KQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGkgKm1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShtYXN0ZXIpOwoKCXJldHVybiBfX3Jhd19yZWFkbChtY3NwaS0+YmFzZSArIGlkeCk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtY3NwaV93cml0ZV9jc19yZWcoY29uc3Qgc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwKCQlpbnQgaWR4LCB1MzIgdmFsKQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJKmNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoKCV9fcmF3X3dyaXRlbCh2YWwsIGNzLT5iYXNlICsgIGlkeCk7Cn0KCnN0YXRpYyBpbmxpbmUgdTMyIG1jc3BpX3JlYWRfY3NfcmVnKGNvbnN0IHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIGludCBpZHgpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaV9jcwkqY3MgPSBzcGktPmNvbnRyb2xsZXJfc3RhdGU7CgoJcmV0dXJuIF9fcmF3X3JlYWRsKGNzLT5iYXNlICsgaWR4KTsKfQoKc3RhdGljIGlubGluZSB1MzIgbWNzcGlfY2FjaGVkX2NoY29uZjAoY29uc3Qgc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKewoJc3RydWN0IG9tYXAyX21jc3BpX2NzICpjcyA9IHNwaS0+Y29udHJvbGxlcl9zdGF0ZTsKCglyZXR1cm4gY3MtPmNoY29uZjA7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtY3NwaV93cml0ZV9jaGNvbmYwKGNvbnN0IHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIHUzMiB2YWwpCnsKCXN0cnVjdCBvbWFwMl9tY3NwaV9jcyAqY3MgPSBzcGktPmNvbnRyb2xsZXJfc3RhdGU7CgoJY3MtPmNoY29uZjAgPSB2YWw7CgltY3NwaV93cml0ZV9jc19yZWcoc3BpLCBPTUFQMl9NQ1NQSV9DSENPTkYwLCB2YWwpOwoJbWNzcGlfcmVhZF9jc19yZWcoc3BpLCBPTUFQMl9NQ1NQSV9DSENPTkYwKTsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfc2V0X2RtYV9yZXEoY29uc3Qgc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwKCQlpbnQgaXNfcmVhZCwgaW50IGVuYWJsZSkKewoJdTMyIGwsIHJ3OwoKCWwgPSBtY3NwaV9jYWNoZWRfY2hjb25mMChzcGkpOwoKCWlmIChpc19yZWFkKSAvKiAxIGlzIHJlYWQsIDAgd3JpdGUgKi8KCQlydyA9IE9NQVAyX01DU1BJX0NIQ09ORl9ETUFSOwoJZWxzZQoJCXJ3ID0gT01BUDJfTUNTUElfQ0hDT05GX0RNQVc7CgoJTU9EX1JFR19CSVQobCwgcncsIGVuYWJsZSk7CgltY3NwaV93cml0ZV9jaGNvbmYwKHNwaSwgbCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX3NldF9lbmFibGUoY29uc3Qgc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwgaW50IGVuYWJsZSkKewoJdTMyIGw7CgoJbCA9IGVuYWJsZSA/IE9NQVAyX01DU1BJX0NIQ1RSTF9FTiA6IDA7CgltY3NwaV93cml0ZV9jc19yZWcoc3BpLCBPTUFQMl9NQ1NQSV9DSENUUkwwLCBsKTsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfZm9yY2VfY3Moc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwgaW50IGNzX2FjdGl2ZSkKewoJdTMyIGw7CgoJbCA9IG1jc3BpX2NhY2hlZF9jaGNvbmYwKHNwaSk7CglNT0RfUkVHX0JJVChsLCBPTUFQMl9NQ1NQSV9DSENPTkZfRk9SQ0UsIGNzX2FjdGl2ZSk7CgltY3NwaV93cml0ZV9jaGNvbmYwKHNwaSwgbCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX3NldF9tYXN0ZXJfbW9kZShzdHJ1Y3Qgc3BpX21hc3RlciAqbWFzdGVyKQp7Cgl1MzIgbDsKCgkvKiBzZXR1cCB3aGVuIHN3aXRjaGluZyBmcm9tIChyZXNldCBkZWZhdWx0KSBzbGF2ZSBtb2RlCgkgKiB0byBzaW5nbGUtY2hhbm5lbCBtYXN0ZXIgbW9kZQoJICovCglsID0gbWNzcGlfcmVhZF9yZWcobWFzdGVyLCBPTUFQMl9NQ1NQSV9NT0RVTENUUkwpOwoJTU9EX1JFR19CSVQobCwgT01BUDJfTUNTUElfTU9EVUxDVFJMX1NURVNULCAwKTsKCU1PRF9SRUdfQklUKGwsIE9NQVAyX01DU1BJX01PRFVMQ1RSTF9NUywgMCk7CglNT0RfUkVHX0JJVChsLCBPTUFQMl9NQ1NQSV9NT0RVTENUUkxfU0lOR0xFLCAxKTsKCW1jc3BpX3dyaXRlX3JlZyhtYXN0ZXIsIE9NQVAyX01DU1BJX01PRFVMQ1RSTCwgbCk7CgoJb21hcDJfbWNzcGlfY3R4W21hc3Rlci0+YnVzX251bSAtIDFdLm1vZHVsY3RybCA9IGw7Cn0KCnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX3Jlc3RvcmVfY3R4KHN0cnVjdCBvbWFwMl9tY3NwaSAqbWNzcGkpCnsKCXN0cnVjdCBzcGlfbWFzdGVyICpzcGlfY250cmw7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MgKmNzOwoJc3BpX2NudHJsID0gbWNzcGktPm1hc3RlcjsKCgkvKiBNY1NQSTogY29udGV4dCByZXN0b3JlICovCgltY3NwaV93cml0ZV9yZWcoc3BpX2NudHJsLCBPTUFQMl9NQ1NQSV9NT0RVTENUUkwsCgkJCW9tYXAyX21jc3BpX2N0eFtzcGlfY250cmwtPmJ1c19udW0gLSAxXS5tb2R1bGN0cmwpOwoKCW1jc3BpX3dyaXRlX3JlZyhzcGlfY250cmwsIE9NQVAyX01DU1BJX1NZU0NPTkZJRywKCQkJb21hcDJfbWNzcGlfY3R4W3NwaV9jbnRybC0+YnVzX251bSAtIDFdLnN5c2NvbmZpZyk7CgoJbWNzcGlfd3JpdGVfcmVnKHNwaV9jbnRybCwgT01BUDJfTUNTUElfV0FLRVVQRU5BQkxFLAoJCQlvbWFwMl9tY3NwaV9jdHhbc3BpX2NudHJsLT5idXNfbnVtIC0gMV0ud2FrZXVwZW5hYmxlKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNzLCAmb21hcDJfbWNzcGlfY3R4W3NwaV9jbnRybC0+YnVzX251bSAtIDFdLmNzLAoJCQlub2RlKQoJCV9fcmF3X3dyaXRlbChjcy0+Y2hjb25mMCwgY3MtPmJhc2UgKyBPTUFQMl9NQ1NQSV9DSENPTkYwKTsKfQpzdGF0aWMgdm9pZCBvbWFwMl9tY3NwaV9kaXNhYmxlX2Nsb2NrcyhzdHJ1Y3Qgb21hcDJfbWNzcGkgKm1jc3BpKQp7CgljbGtfZGlzYWJsZShtY3NwaS0+aWNrKTsKCWNsa19kaXNhYmxlKG1jc3BpLT5mY2spOwp9CgpzdGF0aWMgaW50IG9tYXAyX21jc3BpX2VuYWJsZV9jbG9ja3Moc3RydWN0IG9tYXAyX21jc3BpICptY3NwaSkKewoJaWYgKGNsa19lbmFibGUobWNzcGktPmljaykpCgkJcmV0dXJuIC1FTk9ERVY7CglpZiAoY2xrX2VuYWJsZShtY3NwaS0+ZmNrKSkKCQlyZXR1cm4gLUVOT0RFVjsKCglvbWFwMl9tY3NwaV9yZXN0b3JlX2N0eChtY3NwaSk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB1bnNpZ25lZApvbWFwMl9tY3NwaV90eHJ4X2RtYShzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBzdHJ1Y3Qgc3BpX3RyYW5zZmVyICp4ZmVyKQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGkJKm1jc3BpOwoJc3RydWN0IG9tYXAyX21jc3BpX2NzCSpjcyA9IHNwaS0+Y29udHJvbGxlcl9zdGF0ZTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEgICptY3NwaV9kbWE7Cgl1bnNpZ25lZCBpbnQJCWNvdW50LCBjOwoJdW5zaWduZWQgbG9uZwkJYmFzZSwgdHhfcmVnLCByeF9yZWc7CglpbnQJCQl3b3JkX2xlbiwgZGF0YV90eXBlLCBlbGVtZW50X2NvdW50OwoJdTgJCQkqIHJ4OwoJY29uc3QgdTgJCSogdHg7CgoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKHNwaS0+bWFzdGVyKTsKCW1jc3BpX2RtYSA9ICZtY3NwaS0+ZG1hX2NoYW5uZWxzW3NwaS0+Y2hpcF9zZWxlY3RdOwoKCWNvdW50ID0geGZlci0+bGVuOwoJYyA9IGNvdW50OwoJd29yZF9sZW4gPSBjcy0+d29yZF9sZW47CgoJYmFzZSA9IGNzLT5waHlzOwoJdHhfcmVnID0gYmFzZSArIE9NQVAyX01DU1BJX1RYMDsKCXJ4X3JlZyA9IGJhc2UgKyBPTUFQMl9NQ1NQSV9SWDA7CglyeCA9IHhmZXItPnJ4X2J1ZjsKCXR4ID0geGZlci0+dHhfYnVmOwoKCWlmICh3b3JkX2xlbiA8PSA4KSB7CgkJZGF0YV90eXBlID0gT01BUF9ETUFfREFUQV9UWVBFX1M4OwoJCWVsZW1lbnRfY291bnQgPSBjb3VudDsKCX0gZWxzZSBpZiAod29yZF9sZW4gPD0gMTYpIHsKCQlkYXRhX3R5cGUgPSBPTUFQX0RNQV9EQVRBX1RZUEVfUzE2OwoJCWVsZW1lbnRfY291bnQgPSBjb3VudCA+PiAxOwoJfSBlbHNlIC8qIHdvcmRfbGVuIDw9IDMyICovIHsKCQlkYXRhX3R5cGUgPSBPTUFQX0RNQV9EQVRBX1RZUEVfUzMyOwoJCWVsZW1lbnRfY291bnQgPSBjb3VudCA+PiAyOwoJfQoKCWlmICh0eCAhPSBOVUxMKSB7CgkJb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhtY3NwaV9kbWEtPmRtYV90eF9jaGFubmVsLAoJCQkJZGF0YV90eXBlLCBlbGVtZW50X2NvdW50LCAxLAoJCQkJT01BUF9ETUFfU1lOQ19FTEVNRU5ULAoJCQkJbWNzcGlfZG1hLT5kbWFfdHhfc3luY19kZXYsIDApOwoKCQlvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMobWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCwgMCwKCQkJCU9NQVBfRE1BX0FNT0RFX0NPTlNUQU5ULAoJCQkJdHhfcmVnLCAwLCAwKTsKCgkJb21hcF9zZXRfZG1hX3NyY19wYXJhbXMobWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCwgMCwKCQkJCU9NQVBfRE1BX0FNT0RFX1BPU1RfSU5DLAoJCQkJeGZlci0+dHhfZG1hLCAwLCAwKTsKCX0KCglpZiAocnggIT0gTlVMTCkgewoJCW9tYXBfc2V0X2RtYV90cmFuc2Zlcl9wYXJhbXMobWNzcGlfZG1hLT5kbWFfcnhfY2hhbm5lbCwKCQkJCWRhdGFfdHlwZSwgZWxlbWVudF9jb3VudCAtIDEsIDEsCgkJCQlPTUFQX0RNQV9TWU5DX0VMRU1FTlQsCgkJCQltY3NwaV9kbWEtPmRtYV9yeF9zeW5jX2RldiwgMSk7CgoJCW9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwsIDAsCgkJCQlPTUFQX0RNQV9BTU9ERV9DT05TVEFOVCwKCQkJCXJ4X3JlZywgMCwgMCk7CgoJCW9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyhtY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsLCAwLAoJCQkJT01BUF9ETUFfQU1PREVfUE9TVF9JTkMsCgkJCQl4ZmVyLT5yeF9kbWEsIDAsIDApOwoJfQoKCWlmICh0eCAhPSBOVUxMKSB7CgkJb21hcF9zdGFydF9kbWEobWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCk7CgkJb21hcDJfbWNzcGlfc2V0X2RtYV9yZXEoc3BpLCAwLCAxKTsKCX0KCglpZiAocnggIT0gTlVMTCkgewoJCW9tYXBfc3RhcnRfZG1hKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwpOwoJCW9tYXAyX21jc3BpX3NldF9kbWFfcmVxKHNwaSwgMSwgMSk7Cgl9CgoJaWYgKHR4ICE9IE5VTEwpIHsKCQl3YWl0X2Zvcl9jb21wbGV0aW9uKCZtY3NwaV9kbWEtPmRtYV90eF9jb21wbGV0aW9uKTsKCQlkbWFfdW5tYXBfc2luZ2xlKE5VTEwsIHhmZXItPnR4X2RtYSwgY291bnQsIERNQV9UT19ERVZJQ0UpOwoJfQoKCWlmIChyeCAhPSBOVUxMKSB7CgkJd2FpdF9mb3JfY29tcGxldGlvbigmbWNzcGlfZG1hLT5kbWFfcnhfY29tcGxldGlvbik7CgkJZG1hX3VubWFwX3NpbmdsZShOVUxMLCB4ZmVyLT5yeF9kbWEsIGNvdW50LCBETUFfRlJPTV9ERVZJQ0UpOwoJCW9tYXAyX21jc3BpX3NldF9lbmFibGUoc3BpLCAwKTsKCQlpZiAobGlrZWx5KG1jc3BpX3JlYWRfY3NfcmVnKHNwaSwgT01BUDJfTUNTUElfQ0hTVEFUMCkKCQkJCSYgT01BUDJfTUNTUElfQ0hTVEFUX1JYUykpIHsKCQkJdTMyIHc7CgoJCQl3ID0gbWNzcGlfcmVhZF9jc19yZWcoc3BpLCBPTUFQMl9NQ1NQSV9SWDApOwoJCQlpZiAod29yZF9sZW4gPD0gOCkKCQkJCSgodTggKil4ZmVyLT5yeF9idWYpW2VsZW1lbnRfY291bnQgLSAxXSA9IHc7CgkJCWVsc2UgaWYgKHdvcmRfbGVuIDw9IDE2KQoJCQkJKCh1MTYgKil4ZmVyLT5yeF9idWYpW2VsZW1lbnRfY291bnQgLSAxXSA9IHc7CgkJCWVsc2UgLyogd29yZF9sZW4gPD0gMzIgKi8KCQkJCSgodTMyICopeGZlci0+cnhfYnVmKVtlbGVtZW50X2NvdW50IC0gMV0gPSB3OwoJCX0gZWxzZSB7CgkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiRE1BIFJYIGxhc3Qgd29yZCBlbXB0eSIpOwoJCQljb3VudCAtPSAod29yZF9sZW4gPD0gOCkgID8gMSA6CgkJCQkgKHdvcmRfbGVuIDw9IDE2KSA/IDIgOgoJCQkgICAgICAgLyogd29yZF9sZW4gPD0gMzIgKi8gNDsKCQl9CgkJb21hcDJfbWNzcGlfc2V0X2VuYWJsZShzcGksIDEpOwoJfQoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgaW50IG1jc3BpX3dhaXRfZm9yX3JlZ19iaXQodm9pZCBfX2lvbWVtICpyZWcsIHVuc2lnbmVkIGxvbmcgYml0KQp7Cgl1bnNpZ25lZCBsb25nIHRpbWVvdXQ7CgoJdGltZW91dCA9IGppZmZpZXMgKyBtc2Vjc190b19qaWZmaWVzKDEwMDApOwoJd2hpbGUgKCEoX19yYXdfcmVhZGwocmVnKSAmIGJpdCkpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkKCQkJcmV0dXJuIC0xOwoJCWNwdV9yZWxheCgpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB1bnNpZ25lZApvbWFwMl9tY3NwaV90eHJ4X3BpbyhzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBzdHJ1Y3Qgc3BpX3RyYW5zZmVyICp4ZmVyKQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGkJKm1jc3BpOwoJc3RydWN0IG9tYXAyX21jc3BpX2NzCSpjcyA9IHNwaS0+Y29udHJvbGxlcl9zdGF0ZTsKCXVuc2lnbmVkIGludAkJY291bnQsIGM7Cgl1MzIJCQlsOwoJdm9pZCBfX2lvbWVtCQkqYmFzZSA9IGNzLT5iYXNlOwoJdm9pZCBfX2lvbWVtCQkqdHhfcmVnOwoJdm9pZCBfX2lvbWVtCQkqcnhfcmVnOwoJdm9pZCBfX2lvbWVtCQkqY2hzdGF0X3JlZzsKCWludAkJCXdvcmRfbGVuOwoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShzcGktPm1hc3Rlcik7Cgljb3VudCA9IHhmZXItPmxlbjsKCWMgPSBjb3VudDsKCXdvcmRfbGVuID0gY3MtPndvcmRfbGVuOwoKCWwgPSBtY3NwaV9jYWNoZWRfY2hjb25mMChzcGkpOwoJbCAmPSB+T01BUDJfTUNTUElfQ0hDT05GX1RSTV9NQVNLOwoKCS8qIFdlIHN0b3JlIHRoZSBwcmUtY2FsY3VsYXRlZCByZWdpc3RlciBhZGRyZXNzZXMgb24gc3RhY2sgdG8gc3BlZWQKCSAqIHVwIHRoZSB0cmFuc2ZlciBsb29wLiAqLwoJdHhfcmVnCQk9IGJhc2UgKyBPTUFQMl9NQ1NQSV9UWDA7CglyeF9yZWcJCT0gYmFzZSArIE9NQVAyX01DU1BJX1JYMDsKCWNoc3RhdF9yZWcJPSBiYXNlICsgT01BUDJfTUNTUElfQ0hTVEFUMDsKCglpZiAod29yZF9sZW4gPD0gOCkgewoJCXU4CQkqcng7CgkJY29uc3QgdTgJKnR4OwoKCQlyeCA9IHhmZXItPnJ4X2J1ZjsKCQl0eCA9IHhmZXItPnR4X2J1ZjsKCgkJZG8gewoJCQljIC09IDE7CgkJCWlmICh0eCAhPSBOVUxMKSB7CgkJCQlpZiAobWNzcGlfd2FpdF9mb3JfcmVnX2JpdChjaHN0YXRfcmVnLAoJCQkJCQlPTUFQMl9NQ1NQSV9DSFNUQVRfVFhTKSA8IDApIHsKCQkJCQlkZXZfZXJyKCZzcGktPmRldiwgIlRYUyB0aW1lZCBvdXRcbiIpOwoJCQkJCWdvdG8gb3V0OwoJCQkJfQojaWZkZWYgVkVSQk9TRQoJCQkJZGV2X2RiZygmc3BpLT5kZXYsICJ3cml0ZS0lZCAlMDJ4XG4iLAoJCQkJCQl3b3JkX2xlbiwgKnR4KTsKI2VuZGlmCgkJCQlfX3Jhd193cml0ZWwoKnR4KyssIHR4X3JlZyk7CgkJCX0KCQkJaWYgKHJ4ICE9IE5VTEwpIHsKCQkJCWlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9SWFMpIDwgMCkgewoJCQkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiUlhTIHRpbWVkIG91dFxuIik7CgkJCQkJZ290byBvdXQ7CgkJCQl9CgkJCQkvKiBwcmV2ZW50IGxhc3QgUlhfT05MWSByZWFkIGZyb20gdHJpZ2dlcmluZwoJCQkJICogbW9yZSB3b3JkIGkvbzogc3dpdGNoIHRvIHJ4K3R4CgkJCQkgKi8KCQkJCWlmIChjID09IDAgJiYgdHggPT0gTlVMTCkKCQkJCQltY3NwaV93cml0ZV9jaGNvbmYwKHNwaSwgbCk7CgkJCQkqcngrKyA9IF9fcmF3X3JlYWRsKHJ4X3JlZyk7CiNpZmRlZiBWRVJCT1NFCgkJCQlkZXZfZGJnKCZzcGktPmRldiwgInJlYWQtJWQgJTAyeFxuIiwKCQkJCQkJd29yZF9sZW4sICoocnggLSAxKSk7CiNlbmRpZgoJCQl9CgkJfSB3aGlsZSAoYyk7Cgl9IGVsc2UgaWYgKHdvcmRfbGVuIDw9IDE2KSB7CgkJdTE2CQkqcng7CgkJY29uc3QgdTE2CSp0eDsKCgkJcnggPSB4ZmVyLT5yeF9idWY7CgkJdHggPSB4ZmVyLT50eF9idWY7CgkJZG8gewoJCQljIC09IDI7CgkJCWlmICh0eCAhPSBOVUxMKSB7CgkJCQlpZiAobWNzcGlfd2FpdF9mb3JfcmVnX2JpdChjaHN0YXRfcmVnLAoJCQkJCQlPTUFQMl9NQ1NQSV9DSFNUQVRfVFhTKSA8IDApIHsKCQkJCQlkZXZfZXJyKCZzcGktPmRldiwgIlRYUyB0aW1lZCBvdXRcbiIpOwoJCQkJCWdvdG8gb3V0OwoJCQkJfQojaWZkZWYgVkVSQk9TRQoJCQkJZGV2X2RiZygmc3BpLT5kZXYsICJ3cml0ZS0lZCAlMDR4XG4iLAoJCQkJCQl3b3JkX2xlbiwgKnR4KTsKI2VuZGlmCgkJCQlfX3Jhd193cml0ZWwoKnR4KyssIHR4X3JlZyk7CgkJCX0KCQkJaWYgKHJ4ICE9IE5VTEwpIHsKCQkJCWlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9SWFMpIDwgMCkgewoJCQkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiUlhTIHRpbWVkIG91dFxuIik7CgkJCQkJZ290byBvdXQ7CgkJCQl9CgkJCQkvKiBwcmV2ZW50IGxhc3QgUlhfT05MWSByZWFkIGZyb20gdHJpZ2dlcmluZwoJCQkJICogbW9yZSB3b3JkIGkvbzogc3dpdGNoIHRvIHJ4K3R4CgkJCQkgKi8KCQkJCWlmIChjID09IDAgJiYgdHggPT0gTlVMTCkKCQkJCQltY3NwaV93cml0ZV9jaGNvbmYwKHNwaSwgbCk7CgkJCQkqcngrKyA9IF9fcmF3X3JlYWRsKHJ4X3JlZyk7CiNpZmRlZiBWRVJCT1NFCgkJCQlkZXZfZGJnKCZzcGktPmRldiwgInJlYWQtJWQgJTA0eFxuIiwKCQkJCQkJd29yZF9sZW4sICoocnggLSAxKSk7CiNlbmRpZgoJCQl9CgkJfSB3aGlsZSAoYyk7Cgl9IGVsc2UgaWYgKHdvcmRfbGVuIDw9IDMyKSB7CgkJdTMyCQkqcng7CgkJY29uc3QgdTMyCSp0eDsKCgkJcnggPSB4ZmVyLT5yeF9idWY7CgkJdHggPSB4ZmVyLT50eF9idWY7CgkJZG8gewoJCQljIC09IDQ7CgkJCWlmICh0eCAhPSBOVUxMKSB7CgkJCQlpZiAobWNzcGlfd2FpdF9mb3JfcmVnX2JpdChjaHN0YXRfcmVnLAoJCQkJCQlPTUFQMl9NQ1NQSV9DSFNUQVRfVFhTKSA8IDApIHsKCQkJCQlkZXZfZXJyKCZzcGktPmRldiwgIlRYUyB0aW1lZCBvdXRcbiIpOwoJCQkJCWdvdG8gb3V0OwoJCQkJfQojaWZkZWYgVkVSQk9TRQoJCQkJZGV2X2RiZygmc3BpLT5kZXYsICJ3cml0ZS0lZCAlMDh4XG4iLAoJCQkJCQl3b3JkX2xlbiwgKnR4KTsKI2VuZGlmCgkJCQlfX3Jhd193cml0ZWwoKnR4KyssIHR4X3JlZyk7CgkJCX0KCQkJaWYgKHJ4ICE9IE5VTEwpIHsKCQkJCWlmIChtY3NwaV93YWl0X2Zvcl9yZWdfYml0KGNoc3RhdF9yZWcsCgkJCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9SWFMpIDwgMCkgewoJCQkJCWRldl9lcnIoJnNwaS0+ZGV2LCAiUlhTIHRpbWVkIG91dFxuIik7CgkJCQkJZ290byBvdXQ7CgkJCQl9CgkJCQkvKiBwcmV2ZW50IGxhc3QgUlhfT05MWSByZWFkIGZyb20gdHJpZ2dlcmluZwoJCQkJICogbW9yZSB3b3JkIGkvbzogc3dpdGNoIHRvIHJ4K3R4CgkJCQkgKi8KCQkJCWlmIChjID09IDAgJiYgdHggPT0gTlVMTCkKCQkJCQltY3NwaV93cml0ZV9jaGNvbmYwKHNwaSwgbCk7CgkJCQkqcngrKyA9IF9fcmF3X3JlYWRsKHJ4X3JlZyk7CiNpZmRlZiBWRVJCT1NFCgkJCQlkZXZfZGJnKCZzcGktPmRldiwgInJlYWQtJWQgJTA4eFxuIiwKCQkJCQkJd29yZF9sZW4sICoocnggLSAxKSk7CiNlbmRpZgoJCQl9CgkJfSB3aGlsZSAoYyk7Cgl9CgoJLyogZm9yIFRYX09OTFkgbW9kZSwgYmUgc3VyZSBhbGwgd29yZHMgaGF2ZSBzaGlmdGVkIG91dCAqLwoJaWYgKHhmZXItPnJ4X2J1ZiA9PSBOVUxMKSB7CgkJaWYgKG1jc3BpX3dhaXRfZm9yX3JlZ19iaXQoY2hzdGF0X3JlZywKCQkJCU9NQVAyX01DU1BJX0NIU1RBVF9UWFMpIDwgMCkgewoJCQlkZXZfZXJyKCZzcGktPmRldiwgIlRYUyB0aW1lZCBvdXRcbiIpOwoJCX0gZWxzZSBpZiAobWNzcGlfd2FpdF9mb3JfcmVnX2JpdChjaHN0YXRfcmVnLAoJCQkJT01BUDJfTUNTUElfQ0hTVEFUX0VPVCkgPCAwKQoJCQlkZXZfZXJyKCZzcGktPmRldiwgIkVPVCB0aW1lZCBvdXRcbiIpOwoJfQpvdXQ6CglyZXR1cm4gY291bnQgLSBjOwp9CgovKiBjYWxsZWQgb25seSB3aGVuIG5vIHRyYW5zZmVyIGlzIGFjdGl2ZSB0byB0aGlzIGRldmljZSAqLwpzdGF0aWMgaW50IG9tYXAyX21jc3BpX3NldHVwX3RyYW5zZmVyKHN0cnVjdCBzcGlfZGV2aWNlICpzcGksCgkJc3RydWN0IHNwaV90cmFuc2ZlciAqdCkKewoJc3RydWN0IG9tYXAyX21jc3BpX2NzICpjcyA9IHNwaS0+Y29udHJvbGxlcl9zdGF0ZTsKCXN0cnVjdCBvbWFwMl9tY3NwaSAqbWNzcGk7CglzdHJ1Y3Qgc3BpX21hc3RlciAqc3BpX2NudHJsOwoJdTMyIGwgPSAwLCBkaXYgPSAwOwoJdTggd29yZF9sZW4gPSBzcGktPmJpdHNfcGVyX3dvcmQ7Cgl1MzIgc3BlZWRfaHogPSBzcGktPm1heF9zcGVlZF9oejsKCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEoc3BpLT5tYXN0ZXIpOwoJc3BpX2NudHJsID0gbWNzcGktPm1hc3RlcjsKCglpZiAodCAhPSBOVUxMICYmIHQtPmJpdHNfcGVyX3dvcmQpCgkJd29yZF9sZW4gPSB0LT5iaXRzX3Blcl93b3JkOwoKCWNzLT53b3JkX2xlbiA9IHdvcmRfbGVuOwoKCWlmICh0ICYmIHQtPnNwZWVkX2h6KQoJCXNwZWVkX2h6ID0gdC0+c3BlZWRfaHo7CgoJaWYgKHNwZWVkX2h6KSB7CgkJd2hpbGUgKGRpdiA8PSAxNSAmJiAoT01BUDJfTUNTUElfTUFYX0ZSRVEgLyAoMSA8PCBkaXYpKQoJCQkJCT4gc3BlZWRfaHopCgkJCWRpdisrOwoJfSBlbHNlCgkJZGl2ID0gMTU7CgoJbCA9IG1jc3BpX2NhY2hlZF9jaGNvbmYwKHNwaSk7CgoJLyogc3RhbmRhcmQgNC13aXJlIG1hc3RlciBtb2RlOiAgU0NLLCBNT1NJL291dCwgTUlTTy9pbiwgbkNTCgkgKiBSRVZJU0lUOiB0aGlzIGNvbnRyb2xsZXIgY291bGQgc3VwcG9ydCBTUElfM1dJUkUgbW9kZS4KCSAqLwoJbCAmPSB+KE9NQVAyX01DU1BJX0NIQ09ORl9JU3xPTUFQMl9NQ1NQSV9DSENPTkZfRFBFMSk7CglsIHw9IE9NQVAyX01DU1BJX0NIQ09ORl9EUEUwOwoKCS8qIHdvcmRsZW5ndGggKi8KCWwgJj0gfk9NQVAyX01DU1BJX0NIQ09ORl9XTF9NQVNLOwoJbCB8PSAod29yZF9sZW4gLSAxKSA8PCA3OwoKCS8qIHNldCBjaGlwc2VsZWN0IHBvbGFyaXR5OyBtYW5hZ2Ugd2l0aCBGT1JDRSAqLwoJaWYgKCEoc3BpLT5tb2RlICYgU1BJX0NTX0hJR0gpKQoJCWwgfD0gT01BUDJfTUNTUElfQ0hDT05GX0VQT0w7CS8qIGFjdGl2ZS1sb3c7IG5vcm1hbCAqLwoJZWxzZQoJCWwgJj0gfk9NQVAyX01DU1BJX0NIQ09ORl9FUE9MOwoKCS8qIHNldCBjbG9jayBkaXZpc29yICovCglsICY9IH5PTUFQMl9NQ1NQSV9DSENPTkZfQ0xLRF9NQVNLOwoJbCB8PSBkaXYgPDwgMjsKCgkvKiBzZXQgU1BJIG1vZGUgMC4uMyAqLwoJaWYgKHNwaS0+bW9kZSAmIFNQSV9DUE9MKQoJCWwgfD0gT01BUDJfTUNTUElfQ0hDT05GX1BPTDsKCWVsc2UKCQlsICY9IH5PTUFQMl9NQ1NQSV9DSENPTkZfUE9MOwoJaWYgKHNwaS0+bW9kZSAmIFNQSV9DUEhBKQoJCWwgfD0gT01BUDJfTUNTUElfQ0hDT05GX1BIQTsKCWVsc2UKCQlsICY9IH5PTUFQMl9NQ1NQSV9DSENPTkZfUEhBOwoKCW1jc3BpX3dyaXRlX2NoY29uZjAoc3BpLCBsKTsKCglkZXZfZGJnKCZzcGktPmRldiwgInNldHVwOiBzcGVlZCAlZCwgc2FtcGxlICVzIGVkZ2UsIGNsayAlc1xuIiwKCQkJT01BUDJfTUNTUElfTUFYX0ZSRVEgLyAoMSA8PCBkaXYpLAoJCQkoc3BpLT5tb2RlICYgU1BJX0NQSEEpID8gInRyYWlsaW5nIiA6ICJsZWFkaW5nIiwKCQkJKHNwaS0+bW9kZSAmIFNQSV9DUE9MKSA/ICJpbnZlcnRlZCIgOiAibm9ybWFsIik7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX2RtYV9yeF9jYWxsYmFjayhpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3Qgc3BpX2RldmljZQkqc3BpID0gZGF0YTsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfZG1hCSptY3NwaV9kbWE7CgoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKHNwaS0+bWFzdGVyKTsKCW1jc3BpX2RtYSA9ICYobWNzcGktPmRtYV9jaGFubmVsc1tzcGktPmNoaXBfc2VsZWN0XSk7CgoJY29tcGxldGUoJm1jc3BpX2RtYS0+ZG1hX3J4X2NvbXBsZXRpb24pOwoKCS8qIFdlIG11c3QgZGlzYWJsZSB0aGUgRE1BIFJYIHJlcXVlc3QgKi8KCW9tYXAyX21jc3BpX3NldF9kbWFfcmVxKHNwaSwgMSwgMCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXAyX21jc3BpX2RtYV90eF9jYWxsYmFjayhpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3Qgc3BpX2RldmljZQkqc3BpID0gZGF0YTsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfZG1hCSptY3NwaV9kbWE7CgoJbWNzcGkgPSBzcGlfbWFzdGVyX2dldF9kZXZkYXRhKHNwaS0+bWFzdGVyKTsKCW1jc3BpX2RtYSA9ICYobWNzcGktPmRtYV9jaGFubmVsc1tzcGktPmNoaXBfc2VsZWN0XSk7CgoJY29tcGxldGUoJm1jc3BpX2RtYS0+ZG1hX3R4X2NvbXBsZXRpb24pOwoKCS8qIFdlIG11c3QgZGlzYWJsZSB0aGUgRE1BIFRYIHJlcXVlc3QgKi8KCW9tYXAyX21jc3BpX3NldF9kbWFfcmVxKHNwaSwgMCwgMCk7Cn0KCnN0YXRpYyBpbnQgb21hcDJfbWNzcGlfcmVxdWVzdF9kbWEoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKewoJc3RydWN0IHNwaV9tYXN0ZXIJKm1hc3RlciA9IHNwaS0+bWFzdGVyOwoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCXN0cnVjdCBvbWFwMl9tY3NwaV9kbWEJKm1jc3BpX2RtYTsKCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEobWFzdGVyKTsKCW1jc3BpX2RtYSA9IG1jc3BpLT5kbWFfY2hhbm5lbHMgKyBzcGktPmNoaXBfc2VsZWN0OwoKCWlmIChvbWFwX3JlcXVlc3RfZG1hKG1jc3BpX2RtYS0+ZG1hX3J4X3N5bmNfZGV2LCAiTWNTUEkgUlgiLAoJCQlvbWFwMl9tY3NwaV9kbWFfcnhfY2FsbGJhY2ssIHNwaSwKCQkJJm1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwpKSB7CgkJZGV2X2Vycigmc3BpLT5kZXYsICJubyBSWCBETUEgY2hhbm5lbCBmb3IgTWNTUElcbiIpOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCWlmIChvbWFwX3JlcXVlc3RfZG1hKG1jc3BpX2RtYS0+ZG1hX3R4X3N5bmNfZGV2LCAiTWNTUEkgVFgiLAoJCQlvbWFwMl9tY3NwaV9kbWFfdHhfY2FsbGJhY2ssIHNwaSwKCQkJJm1jc3BpX2RtYS0+ZG1hX3R4X2NoYW5uZWwpKSB7CgkJb21hcF9mcmVlX2RtYShtY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsKTsKCQltY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsID0gLTE7CgkJZGV2X2Vycigmc3BpLT5kZXYsICJubyBUWCBETUEgY2hhbm5lbCBmb3IgTWNTUElcbiIpOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCWluaXRfY29tcGxldGlvbigmbWNzcGlfZG1hLT5kbWFfcnhfY29tcGxldGlvbik7Cglpbml0X2NvbXBsZXRpb24oJm1jc3BpX2RtYS0+ZG1hX3R4X2NvbXBsZXRpb24pOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IG9tYXAyX21jc3BpX3NldHVwKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpCnsKCWludAkJCXJldDsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfZG1hCSptY3NwaV9kbWE7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfY3MJKmNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoKCWlmIChzcGktPmJpdHNfcGVyX3dvcmQgPCA0IHx8IHNwaS0+Yml0c19wZXJfd29yZCA+IDMyKSB7CgkJZGV2X2RiZygmc3BpLT5kZXYsICJzZXR1cDogdW5zdXBwb3J0ZWQgJWQgYml0IHdvcmRzXG4iLAoJCQlzcGktPmJpdHNfcGVyX3dvcmQpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShzcGktPm1hc3Rlcik7CgltY3NwaV9kbWEgPSAmbWNzcGktPmRtYV9jaGFubmVsc1tzcGktPmNoaXBfc2VsZWN0XTsKCglpZiAoIWNzKSB7CgkJY3MgPSBremFsbG9jKHNpemVvZiAqY3MsIEdGUF9LRVJORUwpOwoJCWlmICghY3MpCgkJCXJldHVybiAtRU5PTUVNOwoJCWNzLT5iYXNlID0gbWNzcGktPmJhc2UgKyBzcGktPmNoaXBfc2VsZWN0ICogMHgxNDsKCQljcy0+cGh5cyA9IG1jc3BpLT5waHlzICsgc3BpLT5jaGlwX3NlbGVjdCAqIDB4MTQ7CgkJY3MtPmNoY29uZjAgPSAwOwoJCXNwaS0+Y29udHJvbGxlcl9zdGF0ZSA9IGNzOwoJCS8qIExpbmsgdGhpcyB0byBjb250ZXh0IHNhdmUgbGlzdCAqLwoJCWxpc3RfYWRkX3RhaWwoJmNzLT5ub2RlLAoJCQkmb21hcDJfbWNzcGlfY3R4W21jc3BpLT5tYXN0ZXItPmJ1c19udW0gLSAxXS5jcyk7Cgl9CgoJaWYgKG1jc3BpX2RtYS0+ZG1hX3J4X2NoYW5uZWwgPT0gLTEKCQkJfHwgbWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCA9PSAtMSkgewoJCXJldCA9IG9tYXAyX21jc3BpX3JlcXVlc3RfZG1hKHNwaSk7CgkJaWYgKHJldCA8IDApCgkJCXJldHVybiByZXQ7Cgl9CgoJaWYgKG9tYXAyX21jc3BpX2VuYWJsZV9jbG9ja3MobWNzcGkpKQoJCXJldHVybiAtRU5PREVWOwoKCXJldCA9IG9tYXAyX21jc3BpX3NldHVwX3RyYW5zZmVyKHNwaSwgTlVMTCk7CglvbWFwMl9tY3NwaV9kaXNhYmxlX2Nsb2NrcyhtY3NwaSk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgb21hcDJfbWNzcGlfY2xlYW51cChzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpKQp7CglzdHJ1Y3Qgb21hcDJfbWNzcGkJKm1jc3BpOwoJc3RydWN0IG9tYXAyX21jc3BpX2RtYQkqbWNzcGlfZG1hOwoJc3RydWN0IG9tYXAyX21jc3BpX2NzCSpjczsKCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEoc3BpLT5tYXN0ZXIpOwoJbWNzcGlfZG1hID0gJm1jc3BpLT5kbWFfY2hhbm5lbHNbc3BpLT5jaGlwX3NlbGVjdF07CgoJaWYgKHNwaS0+Y29udHJvbGxlcl9zdGF0ZSkgewoJCS8qIFVubGluayBjb250cm9sbGVyIHN0YXRlIGZyb20gY29udGV4dCBzYXZlIGxpc3QgKi8KCQljcyA9IHNwaS0+Y29udHJvbGxlcl9zdGF0ZTsKCQlsaXN0X2RlbCgmY3MtPm5vZGUpOwoKCQlrZnJlZShzcGktPmNvbnRyb2xsZXJfc3RhdGUpOwoJfQoKCWlmIChtY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsICE9IC0xKSB7CgkJb21hcF9mcmVlX2RtYShtY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsKTsKCQltY3NwaV9kbWEtPmRtYV9yeF9jaGFubmVsID0gLTE7Cgl9CglpZiAobWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCAhPSAtMSkgewoJCW9tYXBfZnJlZV9kbWEobWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCk7CgkJbWNzcGlfZG1hLT5kbWFfdHhfY2hhbm5lbCA9IC0xOwoJfQp9CgpzdGF0aWMgdm9pZCBvbWFwMl9tY3NwaV93b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKewoJc3RydWN0IG9tYXAyX21jc3BpCSptY3NwaTsKCgltY3NwaSA9IGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3Qgb21hcDJfbWNzcGksIHdvcmspOwoJc3Bpbl9sb2NrX2lycSgmbWNzcGktPmxvY2spOwoKCWlmIChvbWFwMl9tY3NwaV9lbmFibGVfY2xvY2tzKG1jc3BpKSkKCQlnb3RvIG91dDsKCgkvKiBXZSBvbmx5IGVuYWJsZSBvbmUgY2hhbm5lbCBhdCBhIHRpbWUgLS0gdGhlIG9uZSB3aG9zZSBtZXNzYWdlIGlzCgkgKiBhdCB0aGUgaGVhZCBvZiB0aGUgcXVldWUgLS0gYWx0aG91Z2ggdGhpcyBjb250cm9sbGVyIHdvdWxkIGdsYWRseQoJICogYXJiaXRyYXRlIGFtb25nIG11bHRpcGxlIGNoYW5uZWxzLiAgVGhpcyBjb3JyZXNwb25kcyB0byAic2luZ2xlCgkgKiBjaGFubmVsIiBtYXN0ZXIgbW9kZS4gIEFzIGEgc2lkZSBlZmZlY3QsIHdlIG5lZWQgdG8gbWFuYWdlIHRoZQoJICogY2hpcHNlbGVjdCB3aXRoIHRoZSBGT1JDRSBiaXQgLi4uIENTICE9IGNoYW5uZWwgZW5hYmxlLgoJICovCgl3aGlsZSAoIWxpc3RfZW1wdHkoJm1jc3BpLT5tc2dfcXVldWUpKSB7CgkJc3RydWN0IHNwaV9tZXNzYWdlCQkqbTsKCQlzdHJ1Y3Qgc3BpX2RldmljZQkJKnNwaTsKCQlzdHJ1Y3Qgc3BpX3RyYW5zZmVyCQkqdCA9IE5VTEw7CgkJaW50CQkJCWNzX2FjdGl2ZSA9IDA7CgkJc3RydWN0IG9tYXAyX21jc3BpX2NzCQkqY3M7CgkJaW50CQkJCXBhcl9vdmVycmlkZSA9IDA7CgkJaW50CQkJCXN0YXR1cyA9IDA7CgkJdTMyCQkJCWNoY29uZjsKCgkJbSA9IGNvbnRhaW5lcl9vZihtY3NwaS0+bXNnX3F1ZXVlLm5leHQsIHN0cnVjdCBzcGlfbWVzc2FnZSwKCQkJCSBxdWV1ZSk7CgoJCWxpc3RfZGVsX2luaXQoJm0tPnF1ZXVlKTsKCQlzcGluX3VubG9ja19pcnEoJm1jc3BpLT5sb2NrKTsKCgkJc3BpID0gbS0+c3BpOwoJCWNzID0gc3BpLT5jb250cm9sbGVyX3N0YXRlOwoKCQlvbWFwMl9tY3NwaV9zZXRfZW5hYmxlKHNwaSwgMSk7CgkJbGlzdF9mb3JfZWFjaF9lbnRyeSh0LCAmbS0+dHJhbnNmZXJzLCB0cmFuc2Zlcl9saXN0KSB7CgkJCWlmICh0LT50eF9idWYgPT0gTlVMTCAmJiB0LT5yeF9idWYgPT0gTlVMTCAmJiB0LT5sZW4pIHsKCQkJCXN0YXR1cyA9IC1FSU5WQUw7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAocGFyX292ZXJyaWRlIHx8IHQtPnNwZWVkX2h6IHx8IHQtPmJpdHNfcGVyX3dvcmQpIHsKCQkJCXBhcl9vdmVycmlkZSA9IDE7CgkJCQlzdGF0dXMgPSBvbWFwMl9tY3NwaV9zZXR1cF90cmFuc2ZlcihzcGksIHQpOwoJCQkJaWYgKHN0YXR1cyA8IDApCgkJCQkJYnJlYWs7CgkJCQlpZiAoIXQtPnNwZWVkX2h6ICYmICF0LT5iaXRzX3Blcl93b3JkKQoJCQkJCXBhcl9vdmVycmlkZSA9IDA7CgkJCX0KCgkJCWlmICghY3NfYWN0aXZlKSB7CgkJCQlvbWFwMl9tY3NwaV9mb3JjZV9jcyhzcGksIDEpOwoJCQkJY3NfYWN0aXZlID0gMTsKCQkJfQoKCQkJY2hjb25mID0gbWNzcGlfY2FjaGVkX2NoY29uZjAoc3BpKTsKCQkJY2hjb25mICY9IH5PTUFQMl9NQ1NQSV9DSENPTkZfVFJNX01BU0s7CgkJCWlmICh0LT50eF9idWYgPT0gTlVMTCkKCQkJCWNoY29uZiB8PSBPTUFQMl9NQ1NQSV9DSENPTkZfVFJNX1JYX09OTFk7CgkJCWVsc2UgaWYgKHQtPnJ4X2J1ZiA9PSBOVUxMKQoJCQkJY2hjb25mIHw9IE9NQVAyX01DU1BJX0NIQ09ORl9UUk1fVFhfT05MWTsKCQkJbWNzcGlfd3JpdGVfY2hjb25mMChzcGksIGNoY29uZik7CgoJCQlpZiAodC0+bGVuKSB7CgkJCQl1bnNpZ25lZAljb3VudDsKCgkJCQkvKiBSWF9PTkxZIG1vZGUgbmVlZHMgZHVtbXkgZGF0YSBpbiBUWCByZWcgKi8KCQkJCWlmICh0LT50eF9idWYgPT0gTlVMTCkKCQkJCQlfX3Jhd193cml0ZWwoMCwgY3MtPmJhc2UKCQkJCQkJCSsgT01BUDJfTUNTUElfVFgwKTsKCgkJCQlpZiAobS0+aXNfZG1hX21hcHBlZCB8fCB0LT5sZW4gPj0gRE1BX01JTl9CWVRFUykKCQkJCQljb3VudCA9IG9tYXAyX21jc3BpX3R4cnhfZG1hKHNwaSwgdCk7CgkJCQllbHNlCgkJCQkJY291bnQgPSBvbWFwMl9tY3NwaV90eHJ4X3BpbyhzcGksIHQpOwoJCQkJbS0+YWN0dWFsX2xlbmd0aCArPSBjb3VudDsKCgkJCQlpZiAoY291bnQgIT0gdC0+bGVuKSB7CgkJCQkJc3RhdHVzID0gLUVJTzsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoKCQkJaWYgKHQtPmRlbGF5X3VzZWNzKQoJCQkJdWRlbGF5KHQtPmRlbGF5X3VzZWNzKTsKCgkJCS8qIGlnbm9yZSB0aGUgImxlYXZlIGl0IG9uIGFmdGVyIGxhc3QgeGZlciIgaGludCAqLwoJCQlpZiAodC0+Y3NfY2hhbmdlKSB7CgkJCQlvbWFwMl9tY3NwaV9mb3JjZV9jcyhzcGksIDApOwoJCQkJY3NfYWN0aXZlID0gMDsKCQkJfQoJCX0KCgkJLyogUmVzdG9yZSBkZWZhdWx0cyBpZiB0aGV5IHdlcmUgb3ZlcnJpZGVuICovCgkJaWYgKHBhcl9vdmVycmlkZSkgewoJCQlwYXJfb3ZlcnJpZGUgPSAwOwoJCQlzdGF0dXMgPSBvbWFwMl9tY3NwaV9zZXR1cF90cmFuc2ZlcihzcGksIE5VTEwpOwoJCX0KCgkJaWYgKGNzX2FjdGl2ZSkKCQkJb21hcDJfbWNzcGlfZm9yY2VfY3Moc3BpLCAwKTsKCgkJb21hcDJfbWNzcGlfc2V0X2VuYWJsZShzcGksIDApOwoKCQltLT5zdGF0dXMgPSBzdGF0dXM7CgkJbS0+Y29tcGxldGUobS0+Y29udGV4dCk7CgoJCXNwaW5fbG9ja19pcnEoJm1jc3BpLT5sb2NrKTsKCX0KCglvbWFwMl9tY3NwaV9kaXNhYmxlX2Nsb2NrcyhtY3NwaSk7CgpvdXQ6CglzcGluX3VubG9ja19pcnEoJm1jc3BpLT5sb2NrKTsKfQoKc3RhdGljIGludCBvbWFwMl9tY3NwaV90cmFuc2ZlcihzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBzdHJ1Y3Qgc3BpX21lc3NhZ2UgKm0pCnsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7Cgl1bnNpZ25lZCBsb25nCQlmbGFnczsKCXN0cnVjdCBzcGlfdHJhbnNmZXIJKnQ7CgoJbS0+YWN0dWFsX2xlbmd0aCA9IDA7CgltLT5zdGF0dXMgPSAwOwoKCS8qIHJlamVjdCBpbnZhbGlkIG1lc3NhZ2VzIGFuZCB0cmFuc2ZlcnMgKi8KCWlmIChsaXN0X2VtcHR5KCZtLT50cmFuc2ZlcnMpIHx8ICFtLT5jb21wbGV0ZSkKCQlyZXR1cm4gLUVJTlZBTDsKCWxpc3RfZm9yX2VhY2hfZW50cnkodCwgJm0tPnRyYW5zZmVycywgdHJhbnNmZXJfbGlzdCkgewoJCWNvbnN0IHZvaWQJKnR4X2J1ZiA9IHQtPnR4X2J1ZjsKCQl2b2lkCQkqcnhfYnVmID0gdC0+cnhfYnVmOwoJCXVuc2lnbmVkCWxlbiA9IHQtPmxlbjsKCgkJaWYgKHQtPnNwZWVkX2h6ID4gT01BUDJfTUNTUElfTUFYX0ZSRVEKCQkJCXx8IChsZW4gJiYgIShyeF9idWYgfHwgdHhfYnVmKSkKCQkJCXx8ICh0LT5iaXRzX3Blcl93b3JkICYmCgkJCQkJKCAgdC0+Yml0c19wZXJfd29yZCA8IDQKCQkJCQl8fCB0LT5iaXRzX3Blcl93b3JkID4gMzIpKSkgewoJCQlkZXZfZGJnKCZzcGktPmRldiwgInRyYW5zZmVyOiAlZCBIeiwgJWQgJXMlcywgJWQgYnB3XG4iLAoJCQkJCXQtPnNwZWVkX2h6LAoJCQkJCWxlbiwKCQkJCQl0eF9idWYgPyAidHgiIDogIiIsCgkJCQkJcnhfYnVmID8gInJ4IiA6ICIiLAoJCQkJCXQtPmJpdHNfcGVyX3dvcmQpOwoJCQlyZXR1cm4gLUVJTlZBTDsKCQl9CgkJaWYgKHQtPnNwZWVkX2h6ICYmIHQtPnNwZWVkX2h6IDwgT01BUDJfTUNTUElfTUFYX0ZSRVEvKDE8PDE2KSkgewoJCQlkZXZfZGJnKCZzcGktPmRldiwgIiVkIEh6IG1heCBleGNlZWRzICVkXG4iLAoJCQkJCXQtPnNwZWVkX2h6LAoJCQkJCU9NQVAyX01DU1BJX01BWF9GUkVRLygxPDwxNikpOwoJCQlyZXR1cm4gLUVJTlZBTDsKCQl9CgoJCWlmIChtLT5pc19kbWFfbWFwcGVkIHx8IGxlbiA8IERNQV9NSU5fQllURVMpCgkJCWNvbnRpbnVlOwoKCQkvKiBEbyBETUEgbWFwcGluZyAiZWFybHkiIGZvciBiZXR0ZXIgZXJyb3IgcmVwb3J0aW5nIGFuZAoJCSAqIGRjYWNoZSB1c2UuICBOb3RlIHRoYXQgaWYgZG1hX3VubWFwX3NpbmdsZSgpIGV2ZXIgc3RhcnRzCgkJICogdG8gZG8gcmVhbCB3b3JrIG9uIEFSTSwgd2UnZCBuZWVkIHRvIGNsZWFuIHVwIG1hcHBpbmdzCgkJICogZm9yIHByZXZpb3VzIHRyYW5zZmVycyBvbiAqQUxMKiBleGl0cyBvZiB0aGlzIGxvb3AuLi4KCQkgKi8KCQlpZiAodHhfYnVmICE9IE5VTEwpIHsKCQkJdC0+dHhfZG1hID0gZG1hX21hcF9zaW5nbGUoJnNwaS0+ZGV2LCAodm9pZCAqKSB0eF9idWYsCgkJCQkJbGVuLCBETUFfVE9fREVWSUNFKTsKCQkJaWYgKGRtYV9tYXBwaW5nX2Vycm9yKCZzcGktPmRldiwgdC0+dHhfZG1hKSkgewoJCQkJZGV2X2RiZygmc3BpLT5kZXYsICJkbWEgJWNYICVkIGJ5dGVzIGVycm9yXG4iLAoJCQkJCQknVCcsIGxlbik7CgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJfQoJCX0KCQlpZiAocnhfYnVmICE9IE5VTEwpIHsKCQkJdC0+cnhfZG1hID0gZG1hX21hcF9zaW5nbGUoJnNwaS0+ZGV2LCByeF9idWYsIHQtPmxlbiwKCQkJCQlETUFfRlJPTV9ERVZJQ0UpOwoJCQlpZiAoZG1hX21hcHBpbmdfZXJyb3IoJnNwaS0+ZGV2LCB0LT5yeF9kbWEpKSB7CgkJCQlkZXZfZGJnKCZzcGktPmRldiwgImRtYSAlY1ggJWQgYnl0ZXMgZXJyb3JcbiIsCgkJCQkJCSdSJywgbGVuKTsKCQkJCWlmICh0eF9idWYgIT0gTlVMTCkKCQkJCQlkbWFfdW5tYXBfc2luZ2xlKE5VTEwsIHQtPnR4X2RtYSwKCQkJCQkJCWxlbiwgRE1BX1RPX0RFVklDRSk7CgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJfQoJCX0KCX0KCgltY3NwaSA9IHNwaV9tYXN0ZXJfZ2V0X2RldmRhdGEoc3BpLT5tYXN0ZXIpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZtY3NwaS0+bG9jaywgZmxhZ3MpOwoJbGlzdF9hZGRfdGFpbCgmbS0+cXVldWUsICZtY3NwaS0+bXNnX3F1ZXVlKTsKCXF1ZXVlX3dvcmsob21hcDJfbWNzcGlfd3EsICZtY3NwaS0+d29yayk7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtY3NwaS0+bG9jaywgZmxhZ3MpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IF9faW5pdCBvbWFwMl9tY3NwaV9yZXNldChzdHJ1Y3Qgb21hcDJfbWNzcGkgKm1jc3BpKQp7CglzdHJ1Y3Qgc3BpX21hc3RlcgkqbWFzdGVyID0gbWNzcGktPm1hc3RlcjsKCXUzMgkJCXRtcDsKCglpZiAob21hcDJfbWNzcGlfZW5hYmxlX2Nsb2NrcyhtY3NwaSkpCgkJcmV0dXJuIC0xOwoKCW1jc3BpX3dyaXRlX3JlZyhtYXN0ZXIsIE9NQVAyX01DU1BJX1NZU0NPTkZJRywKCQkJT01BUDJfTUNTUElfU1lTQ09ORklHX1NPRlRSRVNFVCk7CglkbyB7CgkJdG1wID0gbWNzcGlfcmVhZF9yZWcobWFzdGVyLCBPTUFQMl9NQ1NQSV9TWVNTVEFUVVMpOwoJfSB3aGlsZSAoISh0bXAgJiBPTUFQMl9NQ1NQSV9TWVNTVEFUVVNfUkVTRVRET05FKSk7CgoJdG1wID0gT01BUDJfTUNTUElfU1lTQ09ORklHX0FVVE9JRExFIHwKCQlPTUFQMl9NQ1NQSV9TWVNDT05GSUdfRU5BV0FLRVVQIHwKCQlPTUFQMl9NQ1NQSV9TWVNDT05GSUdfU01BUlRJRExFOwoJbWNzcGlfd3JpdGVfcmVnKG1hc3RlciwgT01BUDJfTUNTUElfU1lTQ09ORklHLCB0bXApOwoJb21hcDJfbWNzcGlfY3R4W21hc3Rlci0+YnVzX251bSAtIDFdLnN5c2NvbmZpZyA9IHRtcDsKCgl0bXAgPSBPTUFQMl9NQ1NQSV9XQUtFVVBFTkFCTEVfV0tFTjsKCW1jc3BpX3dyaXRlX3JlZyhtYXN0ZXIsIE9NQVAyX01DU1BJX1dBS0VVUEVOQUJMRSwgdG1wKTsKCW9tYXAyX21jc3BpX2N0eFttYXN0ZXItPmJ1c19udW0gLSAxXS53YWtldXBlbmFibGUgPSB0bXA7CgoJb21hcDJfbWNzcGlfc2V0X21hc3Rlcl9tb2RlKG1hc3Rlcik7CglvbWFwMl9tY3NwaV9kaXNhYmxlX2Nsb2NrcyhtY3NwaSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHU4IF9faW5pdGRhdGEgc3BpMV9yeGRtYV9pZCBbXSA9IHsKCU9NQVAyNFhYX0RNQV9TUEkxX1JYMCwKCU9NQVAyNFhYX0RNQV9TUEkxX1JYMSwKCU9NQVAyNFhYX0RNQV9TUEkxX1JYMiwKCU9NQVAyNFhYX0RNQV9TUEkxX1JYMywKfTsKCnN0YXRpYyB1OCBfX2luaXRkYXRhIHNwaTFfdHhkbWFfaWQgW10gPSB7CglPTUFQMjRYWF9ETUFfU1BJMV9UWDAsCglPTUFQMjRYWF9ETUFfU1BJMV9UWDEsCglPTUFQMjRYWF9ETUFfU1BJMV9UWDIsCglPTUFQMjRYWF9ETUFfU1BJMV9UWDMsCn07CgpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGkyX3J4ZG1hX2lkW10gPSB7CglPTUFQMjRYWF9ETUFfU1BJMl9SWDAsCglPTUFQMjRYWF9ETUFfU1BJMl9SWDEsCn07CgpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGkyX3R4ZG1hX2lkW10gPSB7CglPTUFQMjRYWF9ETUFfU1BJMl9UWDAsCglPTUFQMjRYWF9ETUFfU1BJMl9UWDEsCn07CgojaWYgZGVmaW5lZChDT05GSUdfQVJDSF9PTUFQMjQzMCkgfHwgZGVmaW5lZChDT05GSUdfQVJDSF9PTUFQMykgXAoJfHwgZGVmaW5lZChDT05GSUdfQVJDSF9PTUFQNCkKc3RhdGljIHU4IF9faW5pdGRhdGEgc3BpM19yeGRtYV9pZFtdID0gewoJT01BUDI0WFhfRE1BX1NQSTNfUlgwLAoJT01BUDI0WFhfRE1BX1NQSTNfUlgxLAp9OwoKc3RhdGljIHU4IF9faW5pdGRhdGEgc3BpM190eGRtYV9pZFtdID0gewoJT01BUDI0WFhfRE1BX1NQSTNfVFgwLAoJT01BUDI0WFhfRE1BX1NQSTNfVFgxLAp9OwojZW5kaWYKCiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAzKSB8fCBkZWZpbmVkKENPTkZJR19BUkNIX09NQVA0KQpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGk0X3J4ZG1hX2lkW10gPSB7CglPTUFQMzRYWF9ETUFfU1BJNF9SWDAsCn07CgpzdGF0aWMgdTggX19pbml0ZGF0YSBzcGk0X3R4ZG1hX2lkW10gPSB7CglPTUFQMzRYWF9ETUFfU1BJNF9UWDAsCn07CiNlbmRpZgoKc3RhdGljIGludCBfX2luaXQgb21hcDJfbWNzcGlfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKewoJc3RydWN0IHNwaV9tYXN0ZXIJKm1hc3RlcjsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3QgcmVzb3VyY2UJCSpyOwoJaW50CQkJc3RhdHVzID0gMCwgaTsKCWNvbnN0IHU4CQkqcnhkbWFfaWQsICp0eGRtYV9pZDsKCXVuc2lnbmVkCQludW1fY2hpcHNlbGVjdDsKCglzd2l0Y2ggKHBkZXYtPmlkKSB7CgljYXNlIDE6CgkJcnhkbWFfaWQgPSBzcGkxX3J4ZG1hX2lkOwoJCXR4ZG1hX2lkID0gc3BpMV90eGRtYV9pZDsKCQludW1fY2hpcHNlbGVjdCA9IDQ7CgkJYnJlYWs7CgljYXNlIDI6CgkJcnhkbWFfaWQgPSBzcGkyX3J4ZG1hX2lkOwoJCXR4ZG1hX2lkID0gc3BpMl90eGRtYV9pZDsKCQludW1fY2hpcHNlbGVjdCA9IDI7CgkJYnJlYWs7CiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAyNDMwKSB8fCBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAzKSBcCgl8fCBkZWZpbmVkKENPTkZJR19BUkNIX09NQVA0KQoJY2FzZSAzOgoJCXJ4ZG1hX2lkID0gc3BpM19yeGRtYV9pZDsKCQl0eGRtYV9pZCA9IHNwaTNfdHhkbWFfaWQ7CgkJbnVtX2NoaXBzZWxlY3QgPSAyOwoJCWJyZWFrOwojZW5kaWYKI2lmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDMpIHx8IGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDQpCgljYXNlIDQ6CgkJcnhkbWFfaWQgPSBzcGk0X3J4ZG1hX2lkOwoJCXR4ZG1hX2lkID0gc3BpNF90eGRtYV9pZDsKCQludW1fY2hpcHNlbGVjdCA9IDE7CgkJYnJlYWs7CiNlbmRpZgoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgltYXN0ZXIgPSBzcGlfYWxsb2NfbWFzdGVyKCZwZGV2LT5kZXYsIHNpemVvZiAqbWNzcGkpOwoJaWYgKG1hc3RlciA9PSBOVUxMKSB7CgkJZGV2X2RiZygmcGRldi0+ZGV2LCAibWFzdGVyIGFsbG9jYXRpb24gZmFpbGVkXG4iKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCgkvKiB0aGUgc3BpLT5tb2RlIGJpdHMgdW5kZXJzdG9vZCBieSB0aGlzIGRyaXZlcjogKi8KCW1hc3Rlci0+bW9kZV9iaXRzID0gU1BJX0NQT0wgfCBTUElfQ1BIQSB8IFNQSV9DU19ISUdIOwoKCWlmIChwZGV2LT5pZCAhPSAtMSkKCQltYXN0ZXItPmJ1c19udW0gPSBwZGV2LT5pZDsKCgltYXN0ZXItPnNldHVwID0gb21hcDJfbWNzcGlfc2V0dXA7CgltYXN0ZXItPnRyYW5zZmVyID0gb21hcDJfbWNzcGlfdHJhbnNmZXI7CgltYXN0ZXItPmNsZWFudXAgPSBvbWFwMl9tY3NwaV9jbGVhbnVwOwoJbWFzdGVyLT5udW1fY2hpcHNlbGVjdCA9IG51bV9jaGlwc2VsZWN0OwoKCWRldl9zZXRfZHJ2ZGF0YSgmcGRldi0+ZGV2LCBtYXN0ZXIpOwoKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShtYXN0ZXIpOwoJbWNzcGktPm1hc3RlciA9IG1hc3RlcjsKCglyID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKCWlmIChyID09IE5VTEwpIHsKCQlzdGF0dXMgPSAtRU5PREVWOwoJCWdvdG8gZXJyMTsKCX0KCWlmICghcmVxdWVzdF9tZW1fcmVnaW9uKHItPnN0YXJ0LCAoci0+ZW5kIC0gci0+c3RhcnQpICsgMSwKCQkJZGV2X25hbWUoJnBkZXYtPmRldikpKSB7CgkJc3RhdHVzID0gLUVCVVNZOwoJCWdvdG8gZXJyMTsKCX0KCgltY3NwaS0+cGh5cyA9IHItPnN0YXJ0OwoJbWNzcGktPmJhc2UgPSBpb3JlbWFwKHItPnN0YXJ0LCByLT5lbmQgLSByLT5zdGFydCArIDEpOwoJaWYgKCFtY3NwaS0+YmFzZSkgewoJCWRldl9kYmcoJnBkZXYtPmRldiwgImNhbid0IGlvcmVtYXAgTUNTUElcbiIpOwoJCXN0YXR1cyA9IC1FTk9NRU07CgkJZ290byBlcnIxYWE7Cgl9CgoJSU5JVF9XT1JLKCZtY3NwaS0+d29yaywgb21hcDJfbWNzcGlfd29yayk7CgoJc3Bpbl9sb2NrX2luaXQoJm1jc3BpLT5sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZtY3NwaS0+bXNnX3F1ZXVlKTsKCUlOSVRfTElTVF9IRUFEKCZvbWFwMl9tY3NwaV9jdHhbbWFzdGVyLT5idXNfbnVtIC0gMV0uY3MpOwoKCW1jc3BpLT5pY2sgPSBjbGtfZ2V0KCZwZGV2LT5kZXYsICJpY2siKTsKCWlmIChJU19FUlIobWNzcGktPmljaykpIHsKCQlkZXZfZGJnKCZwZGV2LT5kZXYsICJjYW4ndCBnZXQgbWNzcGlfaWNrXG4iKTsKCQlzdGF0dXMgPSBQVFJfRVJSKG1jc3BpLT5pY2spOwoJCWdvdG8gZXJyMWE7Cgl9CgltY3NwaS0+ZmNrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAiZmNrIik7CglpZiAoSVNfRVJSKG1jc3BpLT5mY2spKSB7CgkJZGV2X2RiZygmcGRldi0+ZGV2LCAiY2FuJ3QgZ2V0IG1jc3BpX2Zja1xuIik7CgkJc3RhdHVzID0gUFRSX0VSUihtY3NwaS0+ZmNrKTsKCQlnb3RvIGVycjI7Cgl9CgoJbWNzcGktPmRtYV9jaGFubmVscyA9IGtjYWxsb2MobWFzdGVyLT5udW1fY2hpcHNlbGVjdCwKCQkJc2l6ZW9mKHN0cnVjdCBvbWFwMl9tY3NwaV9kbWEpLAoJCQlHRlBfS0VSTkVMKTsKCglpZiAobWNzcGktPmRtYV9jaGFubmVscyA9PSBOVUxMKQoJCWdvdG8gZXJyMzsKCglmb3IgKGkgPSAwOyBpIDwgbnVtX2NoaXBzZWxlY3Q7IGkrKykgewoJCW1jc3BpLT5kbWFfY2hhbm5lbHNbaV0uZG1hX3J4X2NoYW5uZWwgPSAtMTsKCQltY3NwaS0+ZG1hX2NoYW5uZWxzW2ldLmRtYV9yeF9zeW5jX2RldiA9IHJ4ZG1hX2lkW2ldOwoJCW1jc3BpLT5kbWFfY2hhbm5lbHNbaV0uZG1hX3R4X2NoYW5uZWwgPSAtMTsKCQltY3NwaS0+ZG1hX2NoYW5uZWxzW2ldLmRtYV90eF9zeW5jX2RldiA9IHR4ZG1hX2lkW2ldOwoJfQoKCWlmIChvbWFwMl9tY3NwaV9yZXNldChtY3NwaSkgPCAwKQoJCWdvdG8gZXJyNDsKCglzdGF0dXMgPSBzcGlfcmVnaXN0ZXJfbWFzdGVyKG1hc3Rlcik7CglpZiAoc3RhdHVzIDwgMCkKCQlnb3RvIGVycjQ7CgoJcmV0dXJuIHN0YXR1czsKCmVycjQ6CglrZnJlZShtY3NwaS0+ZG1hX2NoYW5uZWxzKTsKZXJyMzoKCWNsa19wdXQobWNzcGktPmZjayk7CmVycjI6CgljbGtfcHV0KG1jc3BpLT5pY2spOwplcnIxYToKCWlvdW5tYXAobWNzcGktPmJhc2UpOwplcnIxYWE6CglyZWxlYXNlX21lbV9yZWdpb24oci0+c3RhcnQsIChyLT5lbmQgLSByLT5zdGFydCkgKyAxKTsKZXJyMToKCXNwaV9tYXN0ZXJfcHV0KG1hc3Rlcik7CglyZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgaW50IF9fZXhpdCBvbWFwMl9tY3NwaV9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKewoJc3RydWN0IHNwaV9tYXN0ZXIJKm1hc3RlcjsKCXN0cnVjdCBvbWFwMl9tY3NwaQkqbWNzcGk7CglzdHJ1Y3Qgb21hcDJfbWNzcGlfZG1hCSpkbWFfY2hhbm5lbHM7CglzdHJ1Y3QgcmVzb3VyY2UJCSpyOwoJdm9pZCBfX2lvbWVtICpiYXNlOwoKCW1hc3RlciA9IGRldl9nZXRfZHJ2ZGF0YSgmcGRldi0+ZGV2KTsKCW1jc3BpID0gc3BpX21hc3Rlcl9nZXRfZGV2ZGF0YShtYXN0ZXIpOwoJZG1hX2NoYW5uZWxzID0gbWNzcGktPmRtYV9jaGFubmVsczsKCgljbGtfcHV0KG1jc3BpLT5mY2spOwoJY2xrX3B1dChtY3NwaS0+aWNrKTsKCglyID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKCXJlbGVhc2VfbWVtX3JlZ2lvbihyLT5zdGFydCwgKHItPmVuZCAtIHItPnN0YXJ0KSArIDEpOwoKCWJhc2UgPSBtY3NwaS0+YmFzZTsKCXNwaV91bnJlZ2lzdGVyX21hc3RlcihtYXN0ZXIpOwoJaW91bm1hcChiYXNlKTsKCWtmcmVlKGRtYV9jaGFubmVscyk7CgoJcmV0dXJuIDA7Cn0KCi8qIHdvcmsgd2l0aCBob3RwbHVnIGFuZCBjb2xkcGx1ZyAqLwpNT0RVTEVfQUxJQVMoInBsYXRmb3JtOm9tYXAyX21jc3BpIik7CgpzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBvbWFwMl9tY3NwaV9kcml2ZXIgPSB7CgkuZHJpdmVyID0gewoJCS5uYW1lID0JCSJvbWFwMl9tY3NwaSIsCgkJLm93bmVyID0JVEhJU19NT0RVTEUsCgl9LAoJLnJlbW92ZSA9CV9fZXhpdF9wKG9tYXAyX21jc3BpX3JlbW92ZSksCn07CgoKc3RhdGljIGludCBfX2luaXQgb21hcDJfbWNzcGlfaW5pdCh2b2lkKQp7CglvbWFwMl9tY3NwaV93cSA9IGNyZWF0ZV9zaW5nbGV0aHJlYWRfd29ya3F1ZXVlKAoJCQkJb21hcDJfbWNzcGlfZHJpdmVyLmRyaXZlci5uYW1lKTsKCWlmIChvbWFwMl9tY3NwaV93cSA9PSBOVUxMKQoJCXJldHVybiAtMTsKCXJldHVybiBwbGF0Zm9ybV9kcml2ZXJfcHJvYmUoJm9tYXAyX21jc3BpX2RyaXZlciwgb21hcDJfbWNzcGlfcHJvYmUpOwp9CnN1YnN5c19pbml0Y2FsbChvbWFwMl9tY3NwaV9pbml0KTsKCnN0YXRpYyB2b2lkIF9fZXhpdCBvbWFwMl9tY3NwaV9leGl0KHZvaWQpCnsKCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZvbWFwMl9tY3NwaV9kcml2ZXIpOwoKCWRlc3Ryb3lfd29ya3F1ZXVlKG9tYXAyX21jc3BpX3dxKTsKfQptb2R1bGVfZXhpdChvbWFwMl9tY3NwaV9leGl0KTsKCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK