ZGlmZiAtLWdpdCBhL2RyaXZlcnMvc2NzaS9tZWdhcmFpZC5jIGIvZHJpdmVycy9zY3NpL21lZ2FyYWlkLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQ3MDdiMgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvc2NzaS9tZWdhcmFpZC5jCkBAIC0wLDAgKzEsNTEyMiBAQAorLyoKKyAqCisgKgkJCUxpbnV4IE1lZ2FSQUlEIGRldmljZSBkcml2ZXIKKyAqCisgKiBDb3B5cmlnaHQgqSAyMDAyICBMU0kgTG9naWMgQ29ycG9yYXRpb24uCisgKgorICoJICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICoJICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKKyAqCSAgIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbgorICoJICAgMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMDIgIFJlZCBIYXQsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCSAgLSBmaXhlcworICoJICAtIHNwZWVkLXVwcyAobGlzdCBoYW5kbGluZyBmaXhlcywgaXNzdWVkX2xpc3QsIG9wdGltaXphdGlvbnMuKQorICoJICAtIGxvdHMgb2YgY2xlYW51cHMuCisgKgorICogQ29weXJpZ2h0IChjKSAyMDAzICBDaHJpc3RvcGggSGVsbHdpZyAgPGhjaEBsc3QuZGU+CisgKgkgIC0gbmV3LXN0eWxlLCBob3RwbHVnLWF3YXJlIHBjaSBwcm9iaW5nIGFuZCBzY3NpIHJlZ2lzdHJhdGlvbgorICoKKyAqIFZlcnNpb24gOiB2Mi4wMC4zIChGZWIgMTksIDIwMDMpIC0gQXR1bCBNdWtrZXIgPEF0dWwuTXVra2VyQGxzaWwuY29tPgorICoKKyAqIERlc2NyaXB0aW9uOiBMaW51eCBkZXZpY2UgZHJpdmVyIGZvciBMU0kgTG9naWMgTWVnYVJBSUQgY29udHJvbGxlcgorICoKKyAqIFN1cHBvcnRlZCBjb250cm9sbGVyczogTWVnYVJBSUQgNDE4LCA0MjgsIDQzOCwgNDY2LCA3NjIsIDQ2NywgNDcxLCA0OTAsIDQ5MworICoJCQkJCTUxOCwgNTIwLCA1MzEsIDUzMgorICoKKyAqIFRoaXMgZHJpdmVyIGlzIHN1cHBvcnRlZCBieSBMU0kgTG9naWMsIHdpdGggYXNzaXN0YW5jZSBmcm9tIFJlZCBIYXQsIERlbGwsCisgKiBhbmQgb3RoZXJzLiBQbGVhc2Ugc2VuZCB1cGRhdGVzIHRvIHRoZSBtYWlsaW5nIGxpc3QKKyAqIGxpbnV4LXNjc2lAdmdlci5rZXJuZWwub3JnIC4KKyAqCisgKi8KKworI2luY2x1ZGUgPGxpbnV4L21tLmg+CisjaW5jbHVkZSA8bGludXgvZnMuaD4KKyNpbmNsdWRlIDxsaW51eC9ibGtkZXYuaD4KKyNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgorI2luY2x1ZGUgPGFzbS9pby5oPgorI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CisjaW5jbHVkZSA8bGludXgvcHJvY19mcy5oPgorI2luY2x1ZGUgPGxpbnV4L3JlYm9vdC5oPgorI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L2xpc3QuaD4KKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KKyNpbmNsdWRlIDxsaW51eC9wY2kuaD4KKyNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CisjaW5jbHVkZSA8c2NzaS9zY3NpY2FtLmg+CisKKyNpbmNsdWRlICJzY3NpLmgiCisjaW5jbHVkZSA8c2NzaS9zY3NpX2hvc3QuaD4KKworI2luY2x1ZGUgIm1lZ2FyYWlkLmgiCisKKyNkZWZpbmUgTUVHQVJBSURfTU9EVUxFX1ZFUlNJT04gIjIuMDAuMyIKKworTU9EVUxFX0FVVEhPUiAoIkxTSSBMb2dpYyBDb3Jwb3JhdGlvbiIpOworTU9EVUxFX0RFU0NSSVBUSU9OICgiTFNJIExvZ2ljIE1lZ2FSQUlEIGRyaXZlciIpOworTU9EVUxFX0xJQ0VOU0UgKCJHUEwiKTsKK01PRFVMRV9WRVJTSU9OKE1FR0FSQUlEX01PRFVMRV9WRVJTSU9OKTsKKworc3RhdGljIHVuc2lnbmVkIGludCBtYXhfY21kX3Blcl9sdW4gPSBERUZfQ01EX1BFUl9MVU47Cittb2R1bGVfcGFyYW0obWF4X2NtZF9wZXJfbHVuLCB1aW50LCAwKTsKK01PRFVMRV9QQVJNX0RFU0MobWF4X2NtZF9wZXJfbHVuLCAiTWF4aW11bSBudW1iZXIgb2YgY29tbWFuZHMgd2hpY2ggY2FuIGJlIGlzc3VlZCB0byBhIHNpbmdsZSBMVU4gKGRlZmF1bHQ9REVGX0NNRF9QRVJfTFVOPTYzKSIpOworCitzdGF0aWMgdW5zaWduZWQgc2hvcnQgaW50IG1heF9zZWN0b3JzX3Blcl9pbyA9IE1BWF9TRUNUT1JTX1BFUl9JTzsKK21vZHVsZV9wYXJhbShtYXhfc2VjdG9yc19wZXJfaW8sIHVzaG9ydCwgMCk7CitNT0RVTEVfUEFSTV9ERVNDKG1heF9zZWN0b3JzX3Blcl9pbywgIk1heGltdW0gbnVtYmVyIG9mIHNlY3RvcnMgcGVyIEkvTyByZXF1ZXN0IChkZWZhdWx0PU1BWF9TRUNUT1JTX1BFUl9JTz0xMjgpIik7CisKKworc3RhdGljIHVuc2lnbmVkIHNob3J0IGludCBtYXhfbWJveF9idXN5X3dhaXQgPSBNQk9YX0JVU1lfV0FJVDsKK21vZHVsZV9wYXJhbShtYXhfbWJveF9idXN5X3dhaXQsIHVzaG9ydCwgMCk7CitNT0RVTEVfUEFSTV9ERVNDKG1heF9tYm94X2J1c3lfd2FpdCwgIk1heGltdW0gd2FpdCBmb3IgbWFpbGJveCBpbiBtaWNyb3NlY29uZHMgaWYgYnVzeSAoZGVmYXVsdD1NQk9YX0JVU1lfV0FJVD0xMCkiKTsKKworI2RlZmluZSBSRElORE9PUihhZGFwdGVyKQkJcmVhZGwoKGFkYXB0ZXIpLT5iYXNlICsgMHgyMCkKKyNkZWZpbmUgUkRPVVRET09SKGFkYXB0ZXIpCQlyZWFkbCgoYWRhcHRlciktPmJhc2UgKyAweDJDKQorI2RlZmluZSBXUklORE9PUihhZGFwdGVyLHZhbHVlKQkJd3JpdGVsKHZhbHVlLCAoYWRhcHRlciktPmJhc2UgKyAweDIwKQorI2RlZmluZSBXUk9VVERPT1IoYWRhcHRlcix2YWx1ZSkJd3JpdGVsKHZhbHVlLCAoYWRhcHRlciktPmJhc2UgKyAweDJDKQorCisvKgorICogR2xvYmFsIHZhcmlhYmxlcworICovCisKK3N0YXRpYyBpbnQgaGJhX2NvdW50Oworc3RhdGljIGFkYXB0ZXJfdCAqaGJhX3NvZnRfc3RhdGVbTUFYX0NPTlRST0xMRVJTXTsKK3N0YXRpYyBzdHJ1Y3QgcHJvY19kaXJfZW50cnkgKm1lZ2FfcHJvY19kaXJfZW50cnk7CisKKy8qIEZvciBjb250cm9sbGVyIHJlLW9yZGVyaW5nICovCitzdGF0aWMgc3RydWN0IG1lZ2FfaGJhcyBtZWdhX2hiYXNbTUFYX0NPTlRST0xMRVJTXTsKKworLyoKKyAqIFRoZSBGaWxlIE9wZXJhdGlvbnMgc3RydWN0dXJlIGZvciB0aGUgc2VyaWFsL2lvY3RsIGludGVyZmFjZSBvZiB0aGUgZHJpdmVyCisgKi8KK3N0YXRpYyBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIG1lZ2FkZXZfZm9wcyA9IHsKKwkub3duZXIJCT0gVEhJU19NT0RVTEUsCisJLmlvY3RsCQk9IG1lZ2FkZXZfaW9jdGwsCisJLm9wZW4JCT0gbWVnYWRldl9vcGVuLAorfTsKKworLyoKKyAqIEFycmF5IHRvIHN0cnVjdHVyZXMgZm9yIHN0b3JpbmcgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb250cm9sbGVycy4gVGhpcworICogaW5mb3JtYXRpb24gaXMgc2VudCB0byB0aGUgdXNlciBsZXZlbCBhcHBsaWNhdGlvbnMsIHdoZW4gdGhleSBkbyBhbiBpb2N0bAorICogZm9yIHRoaXMgaW5mb3JtYXRpb24uCisgKi8KK3N0YXRpYyBzdHJ1Y3QgbWNvbnRyb2xsZXIgbWNvbnRyb2xsZXJbTUFYX0NPTlRST0xMRVJTXTsKKworLyogVGhlIGN1cnJlbnQgZHJpdmVyIHZlcnNpb24gKi8KK3N0YXRpYyB1MzIgZHJpdmVyX3ZlciA9IDB4MDIwMDAwMDA7CisKKy8qIG1ham9yIG51bWJlciB1c2VkIGJ5IHRoZSBkZXZpY2UgZm9yIGNoYXJhY3RlciBpbnRlcmZhY2UgKi8KK3N0YXRpYyBpbnQgbWFqb3I7CisKKyNkZWZpbmUgSVNfUkFJRF9DSChoYmEsIGNoKQkoKChoYmEpLT5tZWdhX2NoX2NsYXNzID4+IChjaCkpICYgMHgwMSkKKworCisvKgorICogRGVidWcgdmFyaWFibGUgdG8gcHJpbnQgc29tZSBkaWFnbm9zdGljIG1lc3NhZ2VzCisgKi8KK3N0YXRpYyBpbnQgdHJhY2VfbGV2ZWw7CisKKy8qKgorICogbWVnYV9zZXR1cF9tYWlsYm94KCkKKyAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIEFsbG9jYXRlcyBhIDggYnl0ZSBhbGlnbmVkIG1lbW9yeSBmb3IgdGhlIGhhbmRzaGFrZSBtYWlsYm94LgorICovCitzdGF0aWMgaW50CittZWdhX3NldHVwX21haWxib3goYWRhcHRlcl90ICphZGFwdGVyKQoreworCXVuc2lnbmVkIGxvbmcJYWxpZ247CisKKwlhZGFwdGVyLT51bmFfbWJveDY0ID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LAorCQkJc2l6ZW9mKG1ib3g2NF90KSwgJmFkYXB0ZXItPnVuYV9tYm94NjRfZG1hKTsKKworCWlmKCAhYWRhcHRlci0+dW5hX21ib3g2NCApIHJldHVybiAtMTsKKwkJCisJYWRhcHRlci0+bWJveCA9ICZhZGFwdGVyLT51bmFfbWJveDY0LT5tYm94OworCisJYWRhcHRlci0+bWJveCA9IChtYm94X3QgKikoKCgodW5zaWduZWQgbG9uZykgYWRhcHRlci0+bWJveCkgKyAxNSkgJgorCQkJKH4wVUwgXiAweEZVTCkpOworCisJYWRhcHRlci0+bWJveDY0ID0gKG1ib3g2NF90ICopKCgodW5zaWduZWQgbG9uZylhZGFwdGVyLT5tYm94KSAtIDgpOworCisJYWxpZ24gPSAoKHZvaWQgKilhZGFwdGVyLT5tYm94KSAtICgodm9pZCAqKSZhZGFwdGVyLT51bmFfbWJveDY0LT5tYm94KTsKKworCWFkYXB0ZXItPm1ib3hfZG1hID0gYWRhcHRlci0+dW5hX21ib3g2NF9kbWEgKyA4ICsgYWxpZ247CisKKwkvKgorCSAqIFJlZ2lzdGVyIHRoZSBtYWlsYm94IGlmIHRoZSBjb250cm9sbGVyIGlzIGFuIGlvLW1hcHBlZCBjb250cm9sbGVyCisJICovCisJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF9JT01BUCApIHsKKworCQlvdXRiX3AoYWRhcHRlci0+bWJveF9kbWEgJiAweEZGLAorCQkJCWFkYXB0ZXItPmhvc3QtPmlvX3BvcnQgKyBNQk9YX1BPUlQwKTsKKworCQlvdXRiX3AoKGFkYXB0ZXItPm1ib3hfZG1hID4+IDgpICYgMHhGRiwKKwkJCQlhZGFwdGVyLT5ob3N0LT5pb19wb3J0ICsgTUJPWF9QT1JUMSk7CisKKwkJb3V0Yl9wKChhZGFwdGVyLT5tYm94X2RtYSA+PiAxNikgJiAweEZGLAorCQkJCWFkYXB0ZXItPmhvc3QtPmlvX3BvcnQgKyBNQk9YX1BPUlQyKTsKKworCQlvdXRiX3AoKGFkYXB0ZXItPm1ib3hfZG1hID4+IDI0KSAmIDB4RkYsCisJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIE1CT1hfUE9SVDMpOworCisJCW91dGJfcChFTkFCTEVfTUJPWF9CWVRFLAorCQkJCWFkYXB0ZXItPmhvc3QtPmlvX3BvcnQgKyBFTkFCTEVfTUJPWF9SRUdJT04pOworCisJCWlycV9hY2soYWRhcHRlcik7CisKKwkJaXJxX2VuYWJsZShhZGFwdGVyKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworCisvKgorICogbWVnYV9xdWVyeV9hZGFwdGVyKCkKKyAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIElzc3VlIHRoZSBhZGFwdGVyIGlucXVpcnkgY29tbWFuZHMgdG8gdGhlIGNvbnRyb2xsZXIgYW5kIGZpbmQgb3V0CisgKiBpbmZvcm1hdGlvbiBhbmQgcGFyYW1ldGVyIGFib3V0IHRoZSBkZXZpY2VzIGF0dGFjaGVkCisgKi8KK3N0YXRpYyBpbnQKK21lZ2FfcXVlcnlfYWRhcHRlcihhZGFwdGVyX3QgKmFkYXB0ZXIpCit7CisJZG1hX2FkZHJfdAlwcm9kX2luZm9fZG1hX2hhbmRsZTsKKwltZWdhX2lucXVpcnkzCSppbnF1aXJ5MzsKKwl1OAlyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CisJbWJveF90CSptYm94OworCWludAlyZXR2YWw7CisKKwkvKiBJbml0aWFsaXplIGFkYXB0ZXIgaW5xdWlyeSBtYWlsYm94ICovCisKKwltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OworCisJbWVtc2V0KCh2b2lkICopYWRhcHRlci0+bWVnYV9idWZmZXIsIDAsIE1FR0FfQlVGRkVSX1NJWkUpOworCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOworCisJLyoKKwkgKiBUcnkgdG8gaXNzdWUgSW5xdWlyeTMgY29tbWFuZAorCSAqIGlmIG5vdCBzdWNjZWVkZWQsIHRoZW4gaXNzdWUgTUVHQV9NQk9YQ01EX0FEQVBURVJJTlEgY29tbWFuZCBhbmQKKwkgKiB1cGRhdGUgZW5xdWlyeTMgc3RydWN0dXJlCisJICovCisJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAodTMyKWFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlOworCisJaW5xdWlyeTMgPSAobWVnYV9pbnF1aXJ5MyAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOworCisJcmF3X21ib3hbMF0gPSBGQ19ORVdfQ09ORklHOwkJLyogaS5lLiBtYm94LT5jbWQ9MHhBMSAqLworCXJhd19tYm94WzJdID0gTkNfU1VCT1BfRU5RVUlSWTM7CS8qIGkuZS4gMHgwRiAqLworCXJhd19tYm94WzNdID0gRU5RM19HRVRfU09MSUNJVEVEX0ZVTEw7CS8qIGkuZS4gMHgwMiAqLworCisJLyogSXNzdWUgYSBibG9ja2luZyBjb21tYW5kIHRvIHRoZSBjYXJkICovCisJaWYgKChyZXR2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpKSkgeworCQkvKiB0aGUgYWRhcHRlciBkb2VzIG5vdCBzdXBwb3J0IDQwbGQgKi8KKworCQltcmFpZF9leHRfaW5xdWlyeQkqZXh0X2lucTsKKwkJbXJhaWRfaW5xdWlyeQkJKmlucTsKKwkJZG1hX2FkZHJfdAkJZG1hX2hhbmRsZTsKKworCQlleHRfaW5xID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LAorCQkJCXNpemVvZihtcmFpZF9leHRfaW5xdWlyeSksICZkbWFfaGFuZGxlKTsKKworCQlpZiggZXh0X2lucSA9PSBOVUxMICkgcmV0dXJuIC0xOworCisJCWlucSA9ICZleHRfaW5xLT5yYWlkX2lucTsKKworCQltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpZG1hX2hhbmRsZTsKKworCQkvKmlzc3VlIG9sZCAweDA0IGNvbW1hbmQgdG8gYWRhcHRlciAqLworCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfQURQRVhUSU5ROworCisJCWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CisKKwkJLyoKKwkJICogdXBkYXRlIEVucXVpcnkzIGFuZCBQcm9kdWN0SW5mbyBzdHJ1Y3R1cmVzIHdpdGgKKwkJICogbXJhaWRfaW5xdWlyeSBzdHJ1Y3R1cmUKKwkJICovCisJCW1lZ2FfOF90b180MGxkKGlucSwgaW5xdWlyeTMsCisJCQkJKG1lZ2FfcHJvZHVjdF9pbmZvICopJmFkYXB0ZXItPnByb2R1Y3RfaW5mbyk7CisKKwkJcGNpX2ZyZWVfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsIHNpemVvZihtcmFpZF9leHRfaW5xdWlyeSksCisJCQkJZXh0X2lucSwgZG1hX2hhbmRsZSk7CisKKwl9IGVsc2UgewkJLyphZGFwdGVyIHN1cHBvcnRzIDQwbGQgKi8KKwkJYWRhcHRlci0+ZmxhZyB8PSBCT0FSRF80MExEOworCisJCS8qCisJCSAqIGdldCBwcm9kdWN0X2luZm8sIHdoaWNoIGlzIHN0YXRpYyBpbmZvcm1hdGlvbiBhbmQgd2lsbCBiZQorCQkgKiB1bmNoYW5nZWQKKwkJICovCisJCXByb2RfaW5mb19kbWFfaGFuZGxlID0gcGNpX21hcF9zaW5nbGUoYWRhcHRlci0+ZGV2LCAodm9pZCAqKQorCQkJCSZhZGFwdGVyLT5wcm9kdWN0X2luZm8sCisJCQkJc2l6ZW9mKG1lZ2FfcHJvZHVjdF9pbmZvKSwgUENJX0RNQV9GUk9NREVWSUNFKTsKKworCQltYm94LT5tX291dC54ZmVyYWRkciA9IHByb2RfaW5mb19kbWFfaGFuZGxlOworCisJCXJhd19tYm94WzBdID0gRkNfTkVXX0NPTkZJRzsJLyogaS5lLiBtYm94LT5jbWQ9MHhBMSAqLworCQlyYXdfbWJveFsyXSA9IE5DX1NVQk9QX1BST0RVQ1RfSU5GTzsJLyogaS5lLiAweDBFICovCisKKwkJaWYgKChyZXR2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpKSkKKwkJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCSJtZWdhcmFpZDogUHJvZHVjdF9pbmZvIGNtZCBmYWlsZWQgd2l0aCBlcnJvcjogJWRcbiIsCisJCQkJcmV0dmFsKTsKKworCQlwY2lfdW5tYXBfc2luZ2xlKGFkYXB0ZXItPmRldiwgcHJvZF9pbmZvX2RtYV9oYW5kbGUsCisJCQkJc2l6ZW9mKG1lZ2FfcHJvZHVjdF9pbmZvKSwgUENJX0RNQV9GUk9NREVWSUNFKTsKKwl9CisKKworCS8qCisJICoga2VybmVsIHNjYW5zIHRoZSBjaGFubmVscyBmcm9tIDAgdG8gPD0gbWF4X2NoYW5uZWwKKwkgKi8KKwlhZGFwdGVyLT5ob3N0LT5tYXhfY2hhbm5lbCA9CisJCWFkYXB0ZXItPnByb2R1Y3RfaW5mby5uY2hhbm5lbHMgKyBOVklSVF9DSEFOIC0xOworCisJYWRhcHRlci0+aG9zdC0+bWF4X2lkID0gMTY7CS8qIG1heCB0YXJnZXRzIHBlciBjaGFubmVsICovCisKKwlhZGFwdGVyLT5ob3N0LT5tYXhfbHVuID0gNzsJLyogVXB0byA3IGx1bnMgZm9yIG5vbiBkaXNrIGRldmljZXMgKi8KKworCWFkYXB0ZXItPmhvc3QtPmNtZF9wZXJfbHVuID0gbWF4X2NtZF9wZXJfbHVuOworCisJYWRhcHRlci0+bnVtbGRydiA9IGlucXVpcnkzLT5udW1fbGRydjsKKworCWFkYXB0ZXItPm1heF9jbWRzID0gYWRhcHRlci0+cHJvZHVjdF9pbmZvLm1heF9jb21tYW5kczsKKworCWlmKGFkYXB0ZXItPm1heF9jbWRzID4gTUFYX0NPTU1BTkRTKQorCQlhZGFwdGVyLT5tYXhfY21kcyA9IE1BWF9DT01NQU5EUzsKKworCWFkYXB0ZXItPmhvc3QtPmNhbl9xdWV1ZSA9IGFkYXB0ZXItPm1heF9jbWRzIC0gMTsKKworCS8qCisJICogR2V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBzY2F0dGVyLWdhdGhlciBlbGVtZW50cyBzdXBwb3J0ZWQgYnkgdGhpcworCSAqIGZpcm13YXJlCisJICovCisJbWVnYV9nZXRfbWF4X3NnbChhZGFwdGVyKTsKKworCWFkYXB0ZXItPmhvc3QtPnNnX3RhYmxlc2l6ZSA9IGFkYXB0ZXItPnNnbGVuOworCisKKwkvKiB1c2UgSFAgZmlybXdhcmUgYW5kIGJpb3MgdmVyc2lvbiBlbmNvZGluZyAqLworCWlmIChhZGFwdGVyLT5wcm9kdWN0X2luZm8uc3Vic3lzdmlkID09IEhQX1NVQlNZU19WSUQpIHsKKwkJc3ByaW50ZiAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIiVjJWQlZC4lZCVkIiwKKwkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uZndfdmVyc2lvblsyXSwKKwkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uZndfdmVyc2lvblsxXSA+PiA4LAorCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzFdICYgMHgwZiwKKwkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uZndfdmVyc2lvblswXSA+PiA4LAorCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzBdICYgMHgwZik7CisJCXNwcmludGYgKGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwgIiVjJWQlZC4lZCVkIiwKKwkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzJdLAorCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMV0gPj4gOCwKKwkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzFdICYgMHgwZiwKKwkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzBdID4+IDgsCisJCQkgYWRhcHRlci0+cHJvZHVjdF9pbmZvLmJpb3NfdmVyc2lvblswXSAmIDB4MGYpOworCX0gZWxzZSB7CisJCW1lbWNweShhZGFwdGVyLT5md192ZXJzaW9uLAorCQkJCShjaGFyICopYWRhcHRlci0+cHJvZHVjdF9pbmZvLmZ3X3ZlcnNpb24sIDQpOworCQlhZGFwdGVyLT5md192ZXJzaW9uWzRdID0gMDsKKworCQltZW1jcHkoYWRhcHRlci0+Ymlvc192ZXJzaW9uLAorCQkJCShjaGFyICopYWRhcHRlci0+cHJvZHVjdF9pbmZvLmJpb3NfdmVyc2lvbiwgNCk7CisKKwkJYWRhcHRlci0+Ymlvc192ZXJzaW9uWzRdID0gMDsKKwl9CisKKwlwcmludGsoS0VSTl9OT1RJQ0UgIm1lZ2FyYWlkOiBbJXM6JXNdIGRldGVjdGVkICVkIGxvZ2ljYWwgZHJpdmVzLlxuIiwKKwkJYWRhcHRlci0+ZndfdmVyc2lvbiwgYWRhcHRlci0+Ymlvc192ZXJzaW9uLCBhZGFwdGVyLT5udW1sZHJ2KTsKKworCS8qCisJICogRG8gd2Ugc3VwcG9ydCBleHRlbmRlZCAoPjEwIGJ5dGVzKSBjZGJzCisJICovCisJYWRhcHRlci0+c3VwcG9ydF9leHRfY2RiID0gbWVnYV9zdXBwb3J0X2V4dF9jZGIoYWRhcHRlcik7CisJaWYgKGFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYikKKwkJcHJpbnRrKEtFUk5fTk9USUNFICJtZWdhcmFpZDogc3VwcG9ydHMgZXh0ZW5kZWQgQ0RCcy5cbiIpOworCisKKwlyZXR1cm4gMDsKK30KKworLyoqCisgKiBtZWdhX3J1bnBlbmRxKCkKKyAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIFJ1bnMgdGhyb3VnaCB0aGUgbGlzdCBvZiBwZW5kaW5nIHJlcXVlc3RzLgorICovCitzdGF0aWMgaW5saW5lIHZvaWQKK21lZ2FfcnVucGVuZHEoYWRhcHRlcl90ICphZGFwdGVyKQoreworCWlmKCFsaXN0X2VtcHR5KCZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpKQorCQlfX21lZ2FfcnVucGVuZHEoYWRhcHRlcik7Cit9CisKKy8qCisgKiBtZWdhcmFpZF9xdWV1ZSgpCisgKiBAc2NtZCAtIElzc3VlIHRoaXMgc2NzaSBjb21tYW5kCisgKiBAZG9uZSAtIHRoZSBjYWxsYmFjayBob29rIGludG8gdGhlIHNjc2kgbWlkLWxheWVyCisgKgorICogVGhlIGNvbW1hbmQgcXVldWluZyBlbnRyeSBwb2ludCBmb3IgdGhlIG1pZC1sYXllci4KKyAqLworc3RhdGljIGludAorbWVnYXJhaWRfcXVldWUoU2NzaV9DbW5kICpzY21kLCB2b2lkICgqZG9uZSkoU2NzaV9DbW5kICopKQoreworCWFkYXB0ZXJfdAkqYWRhcHRlcjsKKwlzY2JfdAkqc2NiOworCWludAlidXN5PTA7CisKKwlhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKXNjbWQtPmRldmljZS0+aG9zdC0+aG9zdGRhdGE7CisKKwlzY21kLT5zY3NpX2RvbmUgPSBkb25lOworCisKKwkvKgorCSAqIEFsbG9jYXRlIGFuZCBidWlsZCBhIFNDQiByZXF1ZXN0CisJICogYnVzeSBmbGFnIHdpbGwgYmUgc2V0IGlmIG1lZ2FfYnVpbGRfY21kKCkgY29tbWFuZCBjb3VsZCBub3QKKwkgKiBhbGxvY2F0ZSBzY2IuIFdlIHdpbGwgcmV0dXJuIG5vbi16ZXJvIHN0YXR1cyBpbiB0aGF0IGNhc2UuCisJICogTk9URTogc2NiIGNhbiBiZSBudWxsIGV2ZW4gdGhvdWdoIGNlcnRhaW4gY29tbWFuZHMgY29tcGxldGVkCisJICogc3VjY2Vzc2Z1bGx5LCBlLmcuLCBNT0RFX1NFTlNFIGFuZCBURVNUX1VOSVRfUkVBRFksIHdlIHdvdWxkCisJICogcmV0dXJuIDAgaW4gdGhhdCBjYXNlLgorCSAqLworCisJc2NiID0gbWVnYV9idWlsZF9jbWQoYWRhcHRlciwgc2NtZCwgJmJ1c3kpOworCisJaWYoc2NiKSB7CisJCXNjYi0+c3RhdGUgfD0gU0NCX1BFTkRROworCQlsaXN0X2FkZF90YWlsKCZzY2ItPmxpc3QsICZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpOworCisJCS8qCisJCSAqIENoZWNrIGlmIHRoZSBIQkEgaXMgaW4gcXVpZXNjZW50IHN0YXRlLCBlLmcuLCBkdXJpbmcgYQorCQkgKiBkZWxldGUgbG9naWNhbCBkcml2ZSBvcGVydGlvbi4gSWYgaXQgaXMsIGRvbid0IHJ1bgorCQkgKiB0aGUgcGVuZGluZ19saXN0LgorCQkgKi8KKwkJaWYoYXRvbWljX3JlYWQoJmFkYXB0ZXItPnF1aWVzY2VudCkgPT0gMCkgeworCQkJbWVnYV9ydW5wZW5kcShhZGFwdGVyKTsKKwkJfQorCQlyZXR1cm4gMDsKKwl9CisKKwlyZXR1cm4gYnVzeTsKK30KKworLyoqCisgKiBtZWdhX2FsbG9jYXRlX3NjYigpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBjbWQgLSBzY3NpIGNvbW1hbmQgZnJvbSB0aGUgbWlkLWxheWVyCisgKgorICogQWxsb2NhdGUgYSBTQ0Igc3RydWN0dXJlLiBUaGlzIGlzIHRoZSBjZW50cmFsIHN0cnVjdHVyZSBmb3IgY29udHJvbGxlcgorICogY29tbWFuZHMuCisgKi8KK3N0YXRpYyBpbmxpbmUgc2NiX3QgKgorbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlcl90ICphZGFwdGVyLCBTY3NpX0NtbmQgKmNtZCkKK3sKKwlzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkID0gJmFkYXB0ZXItPmZyZWVfbGlzdDsKKwlzY2JfdAkqc2NiOworCisJLyogVW5saW5rIGNvbW1hbmQgZnJvbSBGcmVlIExpc3QgKi8KKwlpZiggIWxpc3RfZW1wdHkoaGVhZCkgKSB7CisKKwkJc2NiID0gbGlzdF9lbnRyeShoZWFkLT5uZXh0LCBzY2JfdCwgbGlzdCk7CisKKwkJbGlzdF9kZWxfaW5pdChoZWFkLT5uZXh0KTsKKworCQlzY2ItPnN0YXRlID0gU0NCX0FDVElWRTsKKwkJc2NiLT5jbWQgPSBjbWQ7CisJCXNjYi0+ZG1hX3R5cGUgPSBNRUdBX0RNQV9UWVBFX05PTkU7CisKKwkJcmV0dXJuIHNjYjsKKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworLyoqCisgKiBtZWdhX2dldF9sZHJ2X251bSgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBjbWQgLSBzY3NpIG1pZCBsYXllciBjb21tYW5kCisgKiBAY2hhbm5lbCAtIGNoYW5uZWwgb24gdGhlIGNvbnRyb2xsZXIKKyAqCisgKiBDYWxjdWxhdGUgdGhlIGxvZ2ljYWwgZHJpdmUgbnVtYmVyIGJhc2VkIG9uIHRoZSBpbmZvcm1hdGlvbiBpbiBzY3NpIGNvbW1hbmQKKyAqIGFuZCB0aGUgY2hhbm5lbCBudW1iZXIuCisgKi8KK3N0YXRpYyBpbmxpbmUgaW50CittZWdhX2dldF9sZHJ2X251bShhZGFwdGVyX3QgKmFkYXB0ZXIsIFNjc2lfQ21uZCAqY21kLCBpbnQgY2hhbm5lbCkKK3sKKwlpbnQJCXRndDsKKwlpbnQJCWxkcnZfbnVtOworCisJdGd0ID0gY21kLT5kZXZpY2UtPmlkOworCQorCWlmICggdGd0ID4gYWRhcHRlci0+dGhpc19pZCApCisJCXRndC0tOwkvKiB3ZSBkbyBub3QgZ2V0IGlucXVpcmVzIGZvciBpbml0aWF0b3IgaWQgKi8KKworCWxkcnZfbnVtID0gKGNoYW5uZWwgKiAxNSkgKyB0Z3Q7CisKKworCS8qCisJICogSWYgd2UgaGF2ZSBhIGxvZ2ljYWwgZHJpdmUgd2l0aCBib290IGVuYWJsZWQsIHByb2plY3QgaXQgZmlyc3QKKwkgKi8KKwlpZiggYWRhcHRlci0+Ym9vdF9sZHJ2X2VuYWJsZWQgKSB7CisJCWlmKCBsZHJ2X251bSA9PSAwICkgeworCQkJbGRydl9udW0gPSBhZGFwdGVyLT5ib290X2xkcnY7CisJCX0KKwkJZWxzZSB7CisJCQlpZiggbGRydl9udW0gPD0gYWRhcHRlci0+Ym9vdF9sZHJ2ICkgeworCQkJCWxkcnZfbnVtLS07CisJCQl9CisJCX0KKwl9CisKKwkvKgorCSAqIElmICJkZWxldGUgbG9naWNhbCBkcml2ZSIgZmVhdHVyZSBpcyBlbmFibGVkIG9uIHRoaXMgY29udHJvbGxlci4KKwkgKiBEbyBvbmx5IGlmIGF0IGxlYXN0IG9uZSBkZWxldGUgbG9naWNhbCBkcml2ZSBvcGVyYXRpb24gd2FzIGRvbmUuCisJICoKKwkgKiBBbHNvLCBhZnRlciBsb2dpY2FsIGRyaXZlIGRlbGV0aW9uLCBpbnN0ZWFkIG9mIGxvZ2ljYWwgZHJpdmUgbnVtYmVyLAorCSAqIHRoZSB2YWx1ZSByZXR1cm5lZCBzaG91bGQgYmUgMHg4MCtsb2dpY2FsIGRyaXZlIGlkLgorCSAqCisJICogVGhlc2UgaXMgdmFsaWQgb25seSBmb3IgSU8gY29tbWFuZHMuCisJICovCisKKwlpZiAoYWRhcHRlci0+c3VwcG9ydF9yYW5kb21fZGVsICYmIGFkYXB0ZXItPnJlYWRfbGRpZG1hcCApCisJCXN3aXRjaCAoY21kLT5jbW5kWzBdKSB7CisJCWNhc2UgUkVBRF82OgkvKiBmYWxsIHRocm91Z2ggKi8KKwkJY2FzZSBXUklURV82OgkvKiBmYWxsIHRocm91Z2ggKi8KKwkJY2FzZSBSRUFEXzEwOgkvKiBmYWxsIHRocm91Z2ggKi8KKwkJY2FzZSBXUklURV8xMDoKKwkJCWxkcnZfbnVtICs9IDB4ODA7CisJCX0KKworCXJldHVybiBsZHJ2X251bTsKK30KKworLyoqCisgKiBtZWdhX2J1aWxkX2NtZCgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBjbWQgLSBQcmVwYXJlIHVzaW5nIHRoaXMgc2NzaSBjb21tYW5kCisgKiBAYnVzeSAtIGJ1c3kgZmxhZyBpZiBubyByZXNvdXJjZXMKKyAqCisgKiBQcmVwYXJlcyBhIGNvbW1hbmQgYW5kIHNjYXR0ZXIgZ2F0aGVyIGxpc3QgZm9yIHRoZSBjb250cm9sbGVyLiBUaGlzIHJvdXRpbmUKKyAqIGFsc28gZmluZHMgb3V0IGlmIHRoZSBjb21tYW5kcyBpcyBpbnRlbmRlZCBmb3IgYSBsb2dpY2FsIGRyaXZlIG9yIGEKKyAqIHBoeXNpY2FsIGRldmljZSBhbmQgcHJlcGFyZXMgdGhlIGNvbnRyb2xsZXIgY29tbWFuZCBhY2NvcmRpbmdseS4KKyAqCisgKiBXZSBhbHNvIHJlLW9yZGVyIHRoZSBsb2dpY2FsIGRyaXZlcyBhbmQgcGh5c2ljYWwgZGV2aWNlcyBiYXNlZCBvbiB0aGVpcgorICogYm9vdCBzZXR0aW5ncy4KKyAqLworc3RhdGljIHNjYl90ICoKK21lZ2FfYnVpbGRfY21kKGFkYXB0ZXJfdCAqYWRhcHRlciwgU2NzaV9DbW5kICpjbWQsIGludCAqYnVzeSkKK3sKKwltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1OworCW1lZ2FfcGFzc3RocnUJKnB0aHJ1OworCXNjYl90CSpzY2I7CisJbWJveF90CSptYm94OworCWxvbmcJc2VnOworCWNoYXIJaXNsb2dpY2FsOworCWludAltYXhfbGRydl9udW07CisJaW50CWNoYW5uZWwgPSAwOworCWludAl0YXJnZXQgPSAwOworCWludAlsZHJ2X251bSA9IDA7ICAgLyogbG9naWNhbCBkcml2ZSBudW1iZXIgKi8KKworCisJLyoKKwkgKiBmaWx0ZXIgdGhlIGludGVybmFsIGFuZCBpb2N0bCBjb21tYW5kcworCSAqLworCWlmKChjbWQtPmNtbmRbMF0gPT0gTUVHQV9JTlRFUk5BTF9DTUQpKSB7CisJCXJldHVybiBjbWQtPmJ1ZmZlcjsKKwl9CisKKworCS8qCisJICogV2Uga25vdyB3aGF0IGNoYW5uZWxzIG91ciBsb2dpY2FsIGRyaXZlcyBhcmUgb24gLSBtZWdhX2ZpbmRfY2FyZCgpCisJICovCisJaXNsb2dpY2FsID0gYWRhcHRlci0+bG9nZHJ2X2NoYW5bY21kLT5kZXZpY2UtPmNoYW5uZWxdOworCisJLyoKKwkgKiBUaGUgdGhlb3J5OiBJZiBwaHlzaWNhbCBkcml2ZSBpcyBjaG9zZW4gZm9yIGJvb3QsIGFsbCB0aGUgcGh5c2ljYWwKKwkgKiBkZXZpY2VzIGFyZSBleHBvcnRlZCBiZWZvcmUgdGhlIGxvZ2ljYWwgZHJpdmVzLCBvdGhlcndpc2UgcGh5c2ljYWwKKwkgKiBkZXZpY2VzIGFyZSBwdXNoZWQgYWZ0ZXIgbG9naWNhbCBkcml2ZXMsIGluIHdoaWNoIGNhc2UgLSBLZXJuZWwgc2VlcworCSAqIHRoZSBwaHlzaWNhbCBkZXZpY2VzIG9uIHZpcnR1YWwgY2hhbm5lbCB3aGljaCBpcyBvYnZpb3VzbHkgY29udmVydGVkCisJICogdG8gYWN0dWFsIGNoYW5uZWwgb24gdGhlIEhCQS4KKwkgKi8KKwlpZiggYWRhcHRlci0+Ym9vdF9wZHJ2X2VuYWJsZWQgKSB7CisJCWlmKCBpc2xvZ2ljYWwgKSB7CisJCQkvKiBsb2dpY2FsIGNoYW5uZWwgKi8KKwkJCWNoYW5uZWwgPSBjbWQtPmRldmljZS0+Y2hhbm5lbCAtCisJCQkJYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsKKwkJfQorCQllbHNlIHsKKwkJCS8qIHRoaXMgaXMgcGh5c2ljYWwgY2hhbm5lbCAqLworCQkJY2hhbm5lbCA9IGNtZC0+ZGV2aWNlLT5jaGFubmVsOyAKKwkJCXRhcmdldCA9IGNtZC0+ZGV2aWNlLT5pZDsKKworCQkJLyoKKwkJCSAqIGJvb3QgZnJvbSBhIHBoeXNpY2FsIGRpc2ssIHRoYXQgZGlzayBuZWVkcyB0byBiZQorCQkJICogZXhwb3NlZCBmaXJzdCBJRiBib3RoIHRoZSBjaGFubmVscyBhcmUgU0NTSSwgdGhlbgorCQkJICogYm9vdGluZyBmcm9tIHRoZSBzZWNvbmQgY2hhbm5lbCBpcyBub3QgYWxsb3dlZC4KKwkJCSAqLworCQkJaWYoIHRhcmdldCA9PSAwICkgeworCQkJCXRhcmdldCA9IGFkYXB0ZXItPmJvb3RfcGRydl90Z3Q7CisJCQl9CisJCQllbHNlIGlmKCB0YXJnZXQgPT0gYWRhcHRlci0+Ym9vdF9wZHJ2X3RndCApIHsKKwkJCQl0YXJnZXQgPSAwOworCQkJfQorCQl9CisJfQorCWVsc2UgeworCQlpZiggaXNsb2dpY2FsICkgeworCQkJLyogdGhpcyBpcyB0aGUgbG9naWNhbCBjaGFubmVsICovCisJCQljaGFubmVsID0gY21kLT5kZXZpY2UtPmNoYW5uZWw7CQorCQl9CisJCWVsc2UgeworCQkJLyogcGh5c2ljYWwgY2hhbm5lbCAqLworCQkJY2hhbm5lbCA9IGNtZC0+ZGV2aWNlLT5jaGFubmVsIC0gTlZJUlRfQ0hBTjsJCisJCQl0YXJnZXQgPSBjbWQtPmRldmljZS0+aWQ7CisJCX0KKwl9CisKKworCWlmKGlzbG9naWNhbCkgeworCisJCS8qIGhhdmUganVzdCBMVU4gMCBmb3IgZWFjaCB0YXJnZXQgb24gdmlydHVhbCBjaGFubmVscyAqLworCQlpZiAoY21kLT5kZXZpY2UtPmx1bikgeworCQkJY21kLT5yZXN1bHQgPSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpOworCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKKwkJCXJldHVybiBOVUxMOworCQl9CisKKwkJbGRydl9udW0gPSBtZWdhX2dldF9sZHJ2X251bShhZGFwdGVyLCBjbWQsIGNoYW5uZWwpOworCisKKwkJbWF4X2xkcnZfbnVtID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CisJCQlNQVhfTE9HSUNBTF9EUklWRVNfNDBMRCA6IE1BWF9MT0dJQ0FMX0RSSVZFU184TEQ7CisKKwkJLyoKKwkJICogbWF4X2xkcnZfbnVtIGluY3JlYXNlcyBieSAweDgwIGlmIHNvbWUgbG9naWNhbCBkcml2ZSB3YXMKKwkJICogZGVsZXRlZC4KKwkJICovCisJCWlmKGFkYXB0ZXItPnJlYWRfbGRpZG1hcCkKKwkJCW1heF9sZHJ2X251bSArPSAweDgwOworCisJCWlmKGxkcnZfbnVtID4gbWF4X2xkcnZfbnVtICkgeworCQkJY21kLT5yZXN1bHQgPSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpOworCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKKwkJCXJldHVybiBOVUxMOworCQl9CisKKwl9CisJZWxzZSB7CisJCWlmKCBjbWQtPmRldmljZS0+bHVuID4gNykgeworCQkJLyoKKwkJCSAqIERvIG5vdCBzdXBwb3J0IGx1biA+NyBmb3IgcGh5c2ljYWxseSBhY2Nlc3NlZAorCQkJICogZGV2aWNlcworCQkJICovCisJCQljbWQtPnJlc3VsdCA9IChESURfQkFEX1RBUkdFVCA8PCAxNik7CisJCQljbWQtPnNjc2lfZG9uZShjbWQpOworCQkJcmV0dXJuIE5VTEw7CisJCX0KKwl9CisKKwkvKgorCSAqCisJICogTG9naWNhbCBkcml2ZSBjb21tYW5kcworCSAqCisJICovCisJaWYoaXNsb2dpY2FsKSB7CisJCXN3aXRjaCAoY21kLT5jbW5kWzBdKSB7CisJCWNhc2UgVEVTVF9VTklUX1JFQURZOgorCQkJbWVtc2V0KGNtZC0+cmVxdWVzdF9idWZmZXIsIDAsIGNtZC0+cmVxdWVzdF9idWZmbGVuKTsKKworI2lmIE1FR0FfSEFWRV9DTFVTVEVSSU5HCisJCQkvKgorCQkJICogRG8gd2Ugc3VwcG9ydCBjbHVzdGVyaW5nIGFuZCBpcyB0aGUgc3VwcG9ydCBlbmFibGVkCisJCQkgKiBJZiBubywgcmV0dXJuIHN1Y2Nlc3MgYWx3YXlzCisJCQkgKi8KKwkJCWlmKCAhYWRhcHRlci0+aGFzX2NsdXN0ZXIgKSB7CisJCQkJY21kLT5yZXN1bHQgPSAoRElEX09LIDw8IDE2KTsKKwkJCQljbWQtPnNjc2lfZG9uZShjbWQpOworCQkJCXJldHVybiBOVUxMOworCQkJfQorCisJCQlpZighKHNjYiA9IG1lZ2FfYWxsb2NhdGVfc2NiKGFkYXB0ZXIsIGNtZCkpKSB7CisJCQkJKmJ1c3kgPSAxOworCQkJCXJldHVybiBOVUxMOworCQkJfQorCisJCQlzY2ItPnJhd19tYm94WzBdID0gTUVHQV9DTFVTVEVSX0NNRDsKKwkJCXNjYi0+cmF3X21ib3hbMl0gPSBNRUdBX1JFU0VSVkFUSU9OX1NUQVRVUzsKKwkJCXNjYi0+cmF3X21ib3hbM10gPSBsZHJ2X251bTsKKworCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9OT05FOworCisJCQlyZXR1cm4gc2NiOworI2Vsc2UKKwkJCWNtZC0+cmVzdWx0ID0gKERJRF9PSyA8PCAxNik7CisJCQljbWQtPnNjc2lfZG9uZShjbWQpOworCQkJcmV0dXJuIE5VTEw7CisjZW5kaWYKKworCQljYXNlIE1PREVfU0VOU0U6CisJCQltZW1zZXQoY21kLT5yZXF1ZXN0X2J1ZmZlciwgMCwgY21kLT5jbW5kWzRdKTsKKwkJCWNtZC0+cmVzdWx0ID0gKERJRF9PSyA8PCAxNik7CisJCQljbWQtPnNjc2lfZG9uZShjbWQpOworCQkJcmV0dXJuIE5VTEw7CisKKwkJY2FzZSBSRUFEX0NBUEFDSVRZOgorCQljYXNlIElOUVVJUlk6CisKKwkJCWlmKCEoYWRhcHRlci0+ZmxhZyAmICgxTCA8PCBjbWQtPmRldmljZS0+Y2hhbm5lbCkpKSB7CisKKwkJCQlwcmludGsoS0VSTl9OT1RJQ0UKKwkJCQkJInNjc2klZDogc2Nhbm5pbmcgc2NzaSBjaGFubmVsICVkICIsCisJCQkJCQlhZGFwdGVyLT5ob3N0LT5ob3N0X25vLAorCQkJCQkJY21kLT5kZXZpY2UtPmNoYW5uZWwpOworCQkJCXByaW50aygiZm9yIGxvZ2ljYWwgZHJpdmVzLlxuIik7CisKKwkJCQlhZGFwdGVyLT5mbGFnIHw9ICgxTCA8PCBjbWQtPmRldmljZS0+Y2hhbm5lbCk7CisJCQl9CisKKwkJCS8qIEFsbG9jYXRlIGEgU0NCIGFuZCBpbml0aWFsaXplIHBhc3N0aHJ1ICovCisJCQlpZighKHNjYiA9IG1lZ2FfYWxsb2NhdGVfc2NiKGFkYXB0ZXIsIGNtZCkpKSB7CisJCQkJKmJ1c3kgPSAxOworCQkJCXJldHVybiBOVUxMOworCQkJfQorCQkJcHRocnUgPSBzY2ItPnB0aHJ1OworCisJCQltYm94ID0gKG1ib3hfdCAqKXNjYi0+cmF3X21ib3g7CisJCQltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHNjYi0+cmF3X21ib3gpKTsKKwkJCW1lbXNldChwdGhydSwgMCwgc2l6ZW9mKG1lZ2FfcGFzc3RocnUpKTsKKworCQkJcHRocnUtPnRpbWVvdXQgPSAwOworCQkJcHRocnUtPmFycyA9IDE7CisJCQlwdGhydS0+cmVxc2Vuc2VsZW4gPSAxNDsKKwkJCXB0aHJ1LT5pc2xvZ2ljYWwgPSAxOworCQkJcHRocnUtPmxvZ2RydiA9IGxkcnZfbnVtOworCQkJcHRocnUtPmNkYmxlbiA9IGNtZC0+Y21kX2xlbjsKKwkJCW1lbWNweShwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CisKKwkJCWlmKCBhZGFwdGVyLT5oYXNfNjRiaXRfYWRkciApIHsKKwkJCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDsKKwkJCX0KKwkJCWVsc2UgeworCQkJCW1ib3gtPm1fb3V0LmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKKwkJCX0KKworCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9GUk9NREVWSUNFOworCisJCQlwdGhydS0+bnVtc2dlbGVtZW50cyA9IG1lZ2FfYnVpbGRfc2dsaXN0KGFkYXB0ZXIsIHNjYiwKKwkJCQkmcHRocnUtPmRhdGF4ZmVyYWRkciwgJnB0aHJ1LT5kYXRheGZlcmxlbik7CisKKwkJCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gc2NiLT5wdGhydV9kbWFfYWRkcjsKKworCQkJcmV0dXJuIHNjYjsKKworCQljYXNlIFJFQURfNjoKKwkJY2FzZSBXUklURV82OgorCQljYXNlIFJFQURfMTA6CisJCWNhc2UgV1JJVEVfMTA6CisJCWNhc2UgUkVBRF8xMjoKKwkJY2FzZSBXUklURV8xMjoKKworCQkJLyogQWxsb2NhdGUgYSBTQ0IgYW5kIGluaXRpYWxpemUgbWFpbGJveCAqLworCQkJaWYoIShzY2IgPSBtZWdhX2FsbG9jYXRlX3NjYihhZGFwdGVyLCBjbWQpKSkgeworCQkJCSpidXN5ID0gMTsKKwkJCQlyZXR1cm4gTlVMTDsKKwkJCX0KKwkJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKKworCQkJbWVtc2V0KG1ib3gsIDAsIHNpemVvZihzY2ItPnJhd19tYm94KSk7CisJCQltYm94LT5tX291dC5sb2dkcnYgPSBsZHJ2X251bTsKKworCQkJLyoKKwkJCSAqIEEgbGl0dGxlIGhhY2s6IDJuZCBiaXQgaXMgemVybyBmb3IgYWxsIHNjc2kgcmVhZAorCQkJICogY29tbWFuZHMgYW5kIGlzIHNldCBmb3IgYWxsIHNjc2kgd3JpdGUgY29tbWFuZHMKKwkJCSAqLworCQkJaWYoIGFkYXB0ZXItPmhhc182NGJpdF9hZGRyICkgeworCQkJCW1ib3gtPm1fb3V0LmNtZCA9ICgqY21kLT5jbW5kICYgMHgwMikgPworCQkJCQlNRUdBX01CT1hDTURfTFdSSVRFNjQ6CisJCQkJCU1FR0FfTUJPWENNRF9MUkVBRDY0IDsKKwkJCX0KKwkJCWVsc2UgeworCQkJCW1ib3gtPm1fb3V0LmNtZCA9ICgqY21kLT5jbW5kICYgMHgwMikgPworCQkJCQlNRUdBX01CT1hDTURfTFdSSVRFOgorCQkJCQlNRUdBX01CT1hDTURfTFJFQUQgOworCQkJfQorCisJCQkvKgorCQkJICogNi1ieXRlIFJFQUQoMHgwOCkgb3IgV1JJVEUoMHgwQSkgY2RiCisJCQkgKi8KKwkJCWlmKCBjbWQtPmNtZF9sZW4gPT0gNiApIHsKKwkJCQltYm94LT5tX291dC5udW1zZWN0b3JzID0gKHUzMikgY21kLT5jbW5kWzRdOworCQkJCW1ib3gtPm1fb3V0LmxiYSA9CisJCQkJCSgodTMyKWNtZC0+Y21uZFsxXSA8PCAxNikgfAorCQkJCQkoKHUzMiljbWQtPmNtbmRbMl0gPDwgOCkgfAorCQkJCQkodTMyKWNtZC0+Y21uZFszXTsKKworCQkJCW1ib3gtPm1fb3V0LmxiYSAmPSAweDFGRkZGRjsKKworI2lmIE1FR0FfSEFWRV9TVEFUUworCQkJCS8qCisJCQkJICogVGFrZSBtb2R1bG8gMHg4MCwgc2luY2UgdGhlIGxvZ2ljYWwgZHJpdmUKKwkJCQkgKiBudW1iZXIgaW5jcmVhc2VzIGJ5IDB4ODAgd2hlbiBhIGxvZ2ljYWwKKwkJCQkgKiBkcml2ZSB3YXMgZGVsZXRlZAorCQkJCSAqLworCQkJCWlmICgqY21kLT5jbW5kID09IFJFQURfNikgeworCQkJCQlhZGFwdGVyLT5ucmVhZHNbbGRydl9udW0lMHg4MF0rKzsKKwkJCQkJYWRhcHRlci0+bnJlYWRibG9ja3NbbGRydl9udW0lMHg4MF0gKz0KKwkJCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnM7CisJCQkJfSBlbHNlIHsKKwkJCQkJYWRhcHRlci0+bndyaXRlc1tsZHJ2X251bSUweDgwXSsrOworCQkJCQlhZGFwdGVyLT5ud3JpdGVibG9ja3NbbGRydl9udW0lMHg4MF0gKz0KKwkJCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnM7CisJCQkJfQorI2VuZGlmCisJCQl9CisKKwkJCS8qCisJCQkgKiAxMC1ieXRlIFJFQUQoMHgyOCkgb3IgV1JJVEUoMHgyQSkgY2RiCisJCQkgKi8KKwkJCWlmKCBjbWQtPmNtZF9sZW4gPT0gMTAgKSB7CisJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9ycyA9CisJCQkJCSh1MzIpY21kLT5jbW5kWzhdIHwKKwkJCQkJKCh1MzIpY21kLT5jbW5kWzddIDw8IDgpOworCQkJCW1ib3gtPm1fb3V0LmxiYSA9CisJCQkJCSgodTMyKWNtZC0+Y21uZFsyXSA8PCAyNCkgfAorCQkJCQkoKHUzMiljbWQtPmNtbmRbM10gPDwgMTYpIHwKKwkJCQkJKCh1MzIpY21kLT5jbW5kWzRdIDw8IDgpIHwKKwkJCQkJKHUzMiljbWQtPmNtbmRbNV07CisKKyNpZiBNRUdBX0hBVkVfU1RBVFMKKwkJCQlpZiAoKmNtZC0+Y21uZCA9PSBSRUFEXzEwKSB7CisJCQkJCWFkYXB0ZXItPm5yZWFkc1tsZHJ2X251bSUweDgwXSsrOworCQkJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQorCQkJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9yczsKKwkJCQl9IGVsc2UgeworCQkJCQlhZGFwdGVyLT5ud3JpdGVzW2xkcnZfbnVtJTB4ODBdKys7CisJCQkJCWFkYXB0ZXItPm53cml0ZWJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQorCQkJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9yczsKKwkJCQl9CisjZW5kaWYKKwkJCX0KKworCQkJLyoKKwkJCSAqIDEyLWJ5dGUgUkVBRCgweEE4KSBvciBXUklURSgweEFBKSBjZGIKKwkJCSAqLworCQkJaWYoIGNtZC0+Y21kX2xlbiA9PSAxMiApIHsKKwkJCQltYm94LT5tX291dC5sYmEgPQorCQkJCQkoKHUzMiljbWQtPmNtbmRbMl0gPDwgMjQpIHwKKwkJCQkJKCh1MzIpY21kLT5jbW5kWzNdIDw8IDE2KSB8CisJCQkJCSgodTMyKWNtZC0+Y21uZFs0XSA8PCA4KSB8CisJCQkJCSh1MzIpY21kLT5jbW5kWzVdOworCisJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9ycyA9CisJCQkJCSgodTMyKWNtZC0+Y21uZFs2XSA8PCAyNCkgfAorCQkJCQkoKHUzMiljbWQtPmNtbmRbN10gPDwgMTYpIHwKKwkJCQkJKCh1MzIpY21kLT5jbW5kWzhdIDw8IDgpIHwKKwkJCQkJKHUzMiljbWQtPmNtbmRbOV07CisKKyNpZiBNRUdBX0hBVkVfU1RBVFMKKwkJCQlpZiAoKmNtZC0+Y21uZCA9PSBSRUFEXzEyKSB7CisJCQkJCWFkYXB0ZXItPm5yZWFkc1tsZHJ2X251bSUweDgwXSsrOworCQkJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQorCQkJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9yczsKKwkJCQl9IGVsc2UgeworCQkJCQlhZGFwdGVyLT5ud3JpdGVzW2xkcnZfbnVtJTB4ODBdKys7CisJCQkJCWFkYXB0ZXItPm53cml0ZWJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQorCQkJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9yczsKKwkJCQl9CisjZW5kaWYKKwkJCX0KKworCQkJLyoKKwkJCSAqIElmIGl0IGlzIGEgcmVhZCBjb21tYW5kCisJCQkgKi8KKwkJCWlmKCAoKmNtZC0+Y21uZCAmIDB4MEYpID09IDB4MDggKSB7CisJCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9GUk9NREVWSUNFOworCQkJfQorCQkJZWxzZSB7CisJCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9UT0RFVklDRTsKKwkJCX0KKworCQkJLyogQ2FsY3VsYXRlIFNjYXR0ZXItR2F0aGVyIGluZm8gKi8KKwkJCW1ib3gtPm1fb3V0Lm51bXNnZWxlbWVudHMgPSBtZWdhX2J1aWxkX3NnbGlzdChhZGFwdGVyLCBzY2IsCisJCQkJCSh1MzIgKikmbWJveC0+bV9vdXQueGZlcmFkZHIsICh1MzIgKikmc2VnKTsKKworCQkJcmV0dXJuIHNjYjsKKworI2lmIE1FR0FfSEFWRV9DTFVTVEVSSU5HCisJCWNhc2UgUkVTRVJWRToJLyogRmFsbCB0aHJvdWdoICovCisJCWNhc2UgUkVMRUFTRToKKworCQkJLyoKKwkJCSAqIERvIHdlIHN1cHBvcnQgY2x1c3RlcmluZyBhbmQgaXMgdGhlIHN1cHBvcnQgZW5hYmxlZAorCQkJICovCisJCQlpZiggISBhZGFwdGVyLT5oYXNfY2x1c3RlciApIHsKKworCQkJCWNtZC0+cmVzdWx0ID0gKERJRF9CQURfVEFSR0VUIDw8IDE2KTsKKwkJCQljbWQtPnNjc2lfZG9uZShjbWQpOworCQkJCXJldHVybiBOVUxMOworCQkJfQorCisJCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBtYWlsYm94ICovCisJCQlpZighKHNjYiA9IG1lZ2FfYWxsb2NhdGVfc2NiKGFkYXB0ZXIsIGNtZCkpKSB7CisJCQkJKmJ1c3kgPSAxOworCQkJCXJldHVybiBOVUxMOworCQkJfQorCisJCQlzY2ItPnJhd19tYm94WzBdID0gTUVHQV9DTFVTVEVSX0NNRDsKKwkJCXNjYi0+cmF3X21ib3hbMl0gPSAoICpjbWQtPmNtbmQgPT0gUkVTRVJWRSApID8KKwkJCQlNRUdBX1JFU0VSVkVfTEQgOiBNRUdBX1JFTEVBU0VfTEQ7CisKKwkJCXNjYi0+cmF3X21ib3hbM10gPSBsZHJ2X251bTsKKworCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9OT05FOworCisJCQlyZXR1cm4gc2NiOworI2VuZGlmCisKKwkJZGVmYXVsdDoKKwkJCWNtZC0+cmVzdWx0ID0gKERJRF9CQURfVEFSR0VUIDw8IDE2KTsKKwkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CisJCQlyZXR1cm4gTlVMTDsKKwkJfQorCX0KKworCS8qCisJICogUGFzc3RocnUgZHJpdmUgY29tbWFuZHMKKwkgKi8KKwllbHNlIHsKKwkJLyogQWxsb2NhdGUgYSBTQ0IgYW5kIGluaXRpYWxpemUgcGFzc3RocnUgKi8KKwkJaWYoIShzY2IgPSBtZWdhX2FsbG9jYXRlX3NjYihhZGFwdGVyLCBjbWQpKSkgeworCQkJKmJ1c3kgPSAxOworCQkJcmV0dXJuIE5VTEw7CisJCX0KKworCQltYm94ID0gKG1ib3hfdCAqKXNjYi0+cmF3X21ib3g7CisJCW1lbXNldChtYm94LCAwLCBzaXplb2Yoc2NiLT5yYXdfbWJveCkpOworCisJCWlmKCBhZGFwdGVyLT5zdXBwb3J0X2V4dF9jZGIgKSB7CisKKwkJCWVwdGhydSA9IG1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydShhZGFwdGVyLCBzY2IsIGNtZCwKKwkJCQkJY2hhbm5lbCwgdGFyZ2V0KTsKKworCQkJbWJveC0+bV9vdXQuY21kID0gTUVHQV9NQk9YQ01EX0VYVFBUSFJVOworCisJCQltYm94LT5tX291dC54ZmVyYWRkciA9IHNjYi0+ZXB0aHJ1X2RtYV9hZGRyOworCisJCX0KKwkJZWxzZSB7CisKKwkJCXB0aHJ1ID0gbWVnYV9wcmVwYXJlX3Bhc3N0aHJ1KGFkYXB0ZXIsIHNjYiwgY21kLAorCQkJCQljaGFubmVsLCB0YXJnZXQpOworCisJCQkvKiBJbml0aWFsaXplIG1haWxib3ggKi8KKwkJCWlmKCBhZGFwdGVyLT5oYXNfNjRiaXRfYWRkciApIHsKKwkJCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDsKKwkJCX0KKwkJCWVsc2UgeworCQkJCW1ib3gtPm1fb3V0LmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKKwkJCX0KKworCQkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSBzY2ItPnB0aHJ1X2RtYV9hZGRyOworCisJCX0KKwkJcmV0dXJuIHNjYjsKKwl9CisJcmV0dXJuIE5VTEw7Cit9CisKKworLyoqCisgKiBtZWdhX3ByZXBhcmVfcGFzc3RocnUoKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKiBAc2NiIC0gb3VyIHNjc2kgY29udHJvbCBibG9jaworICogQGNtZCAtIHNjc2kgY29tbWFuZCBmcm9tIHRoZSBtaWQtbGF5ZXIKKyAqIEBjaGFubmVsIC0gYWN0dWFsIGNoYW5uZWwgb24gdGhlIGNvbnRyb2xsZXIKKyAqIEB0YXJnZXQgLSBhY3R1YWwgaWQgb24gdGhlIGNvbnRyb2xsZXIuCisgKgorICogcHJlcGFyZSBhIGNvbW1hbmQgZm9yIHRoZSBzY3NpIHBoeXNpY2FsIGRldmljZXMuCisgKi8KK3N0YXRpYyBtZWdhX3Bhc3N0aHJ1ICoKK21lZ2FfcHJlcGFyZV9wYXNzdGhydShhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIFNjc2lfQ21uZCAqY21kLAorCQlpbnQgY2hhbm5lbCwgaW50IHRhcmdldCkKK3sKKwltZWdhX3Bhc3N0aHJ1ICpwdGhydTsKKworCXB0aHJ1ID0gc2NiLT5wdGhydTsKKwltZW1zZXQocHRocnUsIDAsIHNpemVvZiAobWVnYV9wYXNzdGhydSkpOworCisJLyogMD02c2VjLzE9NjBzZWMvMj0xMG1pbi8zPTNocnMgKi8KKwlwdGhydS0+dGltZW91dCA9IDI7CisKKwlwdGhydS0+YXJzID0gMTsKKwlwdGhydS0+cmVxc2Vuc2VsZW4gPSAxNDsKKwlwdGhydS0+aXNsb2dpY2FsID0gMDsKKworCXB0aHJ1LT5jaGFubmVsID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/IDAgOiBjaGFubmVsOworCisJcHRocnUtPnRhcmdldCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPworCQkoY2hhbm5lbCA8PCA0KSB8IHRhcmdldCA6IHRhcmdldDsKKworCXB0aHJ1LT5jZGJsZW4gPSBjbWQtPmNtZF9sZW47CisJcHRocnUtPmxvZ2RydiA9IGNtZC0+ZGV2aWNlLT5sdW47CisKKwltZW1jcHkocHRocnUtPmNkYiwgY21kLT5jbW5kLCBjbWQtPmNtZF9sZW4pOworCisJLyogTm90IHN1cmUgYWJvdXQgdGhlIGRpcmVjdGlvbiAqLworCXNjYi0+ZG1hX2RpcmVjdGlvbiA9IFBDSV9ETUFfQklESVJFQ1RJT05BTDsKKworCS8qIFNwZWNpYWwgQ29kZSBmb3IgSGFuZGxpbmcgUkVBRF9DQVBBLyBJTlEgdXNpbmcgYm91bmNlIGJ1ZmZlcnMgKi8KKwlzd2l0Y2ggKGNtZC0+Y21uZFswXSkgeworCWNhc2UgSU5RVUlSWToKKwljYXNlIFJFQURfQ0FQQUNJVFk6CisJCWlmKCEoYWRhcHRlci0+ZmxhZyAmICgxTCA8PCBjbWQtPmRldmljZS0+Y2hhbm5lbCkpKSB7CisKKwkJCXByaW50ayhLRVJOX05PVElDRQorCQkJCSJzY3NpJWQ6IHNjYW5uaW5nIHNjc2kgY2hhbm5lbCAlZCBbUCVkXSAiLAorCQkJCQlhZGFwdGVyLT5ob3N0LT5ob3N0X25vLAorCQkJCQljbWQtPmRldmljZS0+Y2hhbm5lbCwgY2hhbm5lbCk7CisJCQlwcmludGsoImZvciBwaHlzaWNhbCBkZXZpY2VzLlxuIik7CisKKwkJCWFkYXB0ZXItPmZsYWcgfD0gKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKTsKKwkJfQorCQkvKiBGYWxsIHRocm91Z2ggKi8KKwlkZWZhdWx0OgorCQlwdGhydS0+bnVtc2dlbGVtZW50cyA9IG1lZ2FfYnVpbGRfc2dsaXN0KGFkYXB0ZXIsIHNjYiwKKwkJCQkmcHRocnUtPmRhdGF4ZmVyYWRkciwgJnB0aHJ1LT5kYXRheGZlcmxlbik7CisJCWJyZWFrOworCX0KKwlyZXR1cm4gcHRocnU7Cit9CisKKworLyoqCisgKiBtZWdhX3ByZXBhcmVfZXh0cGFzc3RocnUoKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKiBAc2NiIC0gb3VyIHNjc2kgY29udHJvbCBibG9jaworICogQGNtZCAtIHNjc2kgY29tbWFuZCBmcm9tIHRoZSBtaWQtbGF5ZXIKKyAqIEBjaGFubmVsIC0gYWN0dWFsIGNoYW5uZWwgb24gdGhlIGNvbnRyb2xsZXIKKyAqIEB0YXJnZXQgLSBhY3R1YWwgaWQgb24gdGhlIGNvbnRyb2xsZXIuCisgKgorICogcHJlcGFyZSBhIGNvbW1hbmQgZm9yIHRoZSBzY3NpIHBoeXNpY2FsIGRldmljZXMuIFRoaXMgcm91bnRpbmUgcHJlcGFyZXMKKyAqIGNvbW1hbmRzIGZvciBkZXZpY2VzIHdoaWNoIGNhbiB0YWtlIGV4dGVuZGVkIENEQnMgKD4xMCBieXRlcykKKyAqLworc3RhdGljIG1lZ2FfZXh0X3Bhc3N0aHJ1ICoKK21lZ2FfcHJlcGFyZV9leHRwYXNzdGhydShhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIFNjc2lfQ21uZCAqY21kLAorCQlpbnQgY2hhbm5lbCwgaW50IHRhcmdldCkKK3sKKwltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1OworCisJZXB0aHJ1ID0gc2NiLT5lcHRocnU7CisJbWVtc2V0KGVwdGhydSwgMCwgc2l6ZW9mKG1lZ2FfZXh0X3Bhc3N0aHJ1KSk7CisKKwkvKiAwPTZzZWMvMT02MHNlYy8yPTEwbWluLzM9M2hycyAqLworCWVwdGhydS0+dGltZW91dCA9IDI7CisKKwllcHRocnUtPmFycyA9IDE7CisJZXB0aHJ1LT5yZXFzZW5zZWxlbiA9IDE0OworCWVwdGhydS0+aXNsb2dpY2FsID0gMDsKKworCWVwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2hhbm5lbDsKKwllcHRocnUtPnRhcmdldCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPworCQkoY2hhbm5lbCA8PCA0KSB8IHRhcmdldCA6IHRhcmdldDsKKworCWVwdGhydS0+Y2RibGVuID0gY21kLT5jbWRfbGVuOworCWVwdGhydS0+bG9nZHJ2ID0gY21kLT5kZXZpY2UtPmx1bjsKKworCW1lbWNweShlcHRocnUtPmNkYiwgY21kLT5jbW5kLCBjbWQtPmNtZF9sZW4pOworCisJLyogTm90IHN1cmUgYWJvdXQgdGhlIGRpcmVjdGlvbiAqLworCXNjYi0+ZG1hX2RpcmVjdGlvbiA9IFBDSV9ETUFfQklESVJFQ1RJT05BTDsKKworCXN3aXRjaChjbWQtPmNtbmRbMF0pIHsKKwljYXNlIElOUVVJUlk6CisJY2FzZSBSRUFEX0NBUEFDSVRZOgorCQlpZighKGFkYXB0ZXItPmZsYWcgJiAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpKSkgeworCisJCQlwcmludGsoS0VSTl9OT1RJQ0UKKwkJCQkic2NzaSVkOiBzY2FubmluZyBzY3NpIGNoYW5uZWwgJWQgW1AlZF0gIiwKKwkJCQkJYWRhcHRlci0+aG9zdC0+aG9zdF9ubywKKwkJCQkJY21kLT5kZXZpY2UtPmNoYW5uZWwsIGNoYW5uZWwpOworCQkJcHJpbnRrKCJmb3IgcGh5c2ljYWwgZGV2aWNlcy5cbiIpOworCisJCQlhZGFwdGVyLT5mbGFnIHw9ICgxTCA8PCBjbWQtPmRldmljZS0+Y2hhbm5lbCk7CisJCX0KKwkJLyogRmFsbCB0aHJvdWdoICovCisJZGVmYXVsdDoKKwkJZXB0aHJ1LT5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAorCQkJCSZlcHRocnUtPmRhdGF4ZmVyYWRkciwgJmVwdGhydS0+ZGF0YXhmZXJsZW4pOworCQlicmVhazsKKwl9CisKKwlyZXR1cm4gZXB0aHJ1OworfQorCitzdGF0aWMgdm9pZAorX19tZWdhX3J1bnBlbmRxKGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwlzY2JfdCAqc2NiOworCXN0cnVjdCBsaXN0X2hlYWQgKnBvcywgKm5leHQ7CisKKwkvKiBJc3N1ZSBhbnkgcGVuZGluZyBjb21tYW5kcyB0byB0aGUgY2FyZCAqLworCWxpc3RfZm9yX2VhY2hfc2FmZShwb3MsIG5leHQsICZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpIHsKKworCQlzY2IgPSBsaXN0X2VudHJ5KHBvcywgc2NiX3QsIGxpc3QpOworCisJCWlmKCAhKHNjYi0+c3RhdGUgJiBTQ0JfSVNTVUVEKSApIHsKKworCQkJaWYoIGlzc3VlX3NjYihhZGFwdGVyLCBzY2IpICE9IDAgKQorCQkJCXJldHVybjsKKwkJfQorCX0KKworCXJldHVybjsKK30KKworCisvKioKKyAqIGlzc3VlX3NjYigpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBzY2IgLSBzY3NpIGNvbnRyb2wgYmxvY2sKKyAqCisgKiBQb3N0IGEgY29tbWFuZCB0byB0aGUgY2FyZCBpZiB0aGUgbWFpbGJveCBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSByZXR1cm4KKyAqIGJ1c3kuIFdlIGFsc28gdGFrZSB0aGUgc2NiIGZyb20gdGhlIHBlbmRpbmcgbGlzdCBpZiB0aGUgbWFpbGJveCBpcworICogYXZhaWxhYmxlLgorICovCitzdGF0aWMgaW50Citpc3N1ZV9zY2IoYWRhcHRlcl90ICphZGFwdGVyLCBzY2JfdCAqc2NiKQoreworCXZvbGF0aWxlIG1ib3g2NF90CSptYm94NjQgPSBhZGFwdGVyLT5tYm94NjQ7CisJdm9sYXRpbGUgbWJveF90CQkqbWJveCA9IGFkYXB0ZXItPm1ib3g7CisJdW5zaWduZWQgaW50CWkgPSAwOworCisJaWYodW5saWtlbHkobWJveC0+bV9pbi5idXN5KSkgeworCQlkbyB7CisJCQl1ZGVsYXkoMSk7CisJCQlpKys7CisJCX0gd2hpbGUoIG1ib3gtPm1faW4uYnVzeSAmJiAoaSA8IG1heF9tYm94X2J1c3lfd2FpdCkgKTsKKworCQlpZihtYm94LT5tX2luLmJ1c3kpIHJldHVybiAtMTsKKwl9CisKKwkvKiBDb3B5IG1haWxib3ggZGF0YSBpbnRvIGhvc3Qgc3RydWN0dXJlICovCisJbWVtY3B5KChjaGFyICopJm1ib3gtPm1fb3V0LCAoY2hhciAqKXNjYi0+cmF3X21ib3gsIAorCQkJc2l6ZW9mKHN0cnVjdCBtYm94X291dCkpOworCisJbWJveC0+bV9vdXQuY21kaWQgPSBzY2ItPmlkeDsJLyogU2V0IGNtZGlkICovCisJbWJveC0+bV9pbi5idXN5ID0gMTsJCS8qIFNldCBidXN5ICovCisKKworCS8qCisJICogSW5jcmVtZW50IHRoZSBwZW5kaW5nIHF1ZXVlIGNvdW50ZXIKKwkgKi8KKwlhdG9taWNfaW5jKCZhZGFwdGVyLT5wZW5kX2NtZHMpOworCisJc3dpdGNoIChtYm94LT5tX291dC5jbWQpIHsKKwljYXNlIE1FR0FfTUJPWENNRF9MUkVBRDY0OgorCWNhc2UgTUVHQV9NQk9YQ01EX0xXUklURTY0OgorCWNhc2UgTUVHQV9NQk9YQ01EX1BBU1NUSFJVNjQ6CisJY2FzZSBNRUdBX01CT1hDTURfRVhUUFRIUlU6CisJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2xvID0gbWJveC0+bV9vdXQueGZlcmFkZHI7CisJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2hpID0gMDsKKwkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAweEZGRkZGRkZGOworCQlicmVhazsKKwlkZWZhdWx0OgorCQltYm94NjQtPnhmZXJfc2VnbWVudF9sbyA9IDA7CisJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2hpID0gMDsKKwl9CisKKwkvKgorCSAqIHBvc3QgdGhlIGNvbW1hbmQKKwkgKi8KKwlzY2ItPnN0YXRlIHw9IFNDQl9JU1NVRUQ7CisKKwlpZiggbGlrZWx5KGFkYXB0ZXItPmZsYWcgJiBCT0FSRF9NRU1NQVApICkgeworCQltYm94LT5tX2luLnBvbGwgPSAwOworCQltYm94LT5tX2luLmFjayA9IDA7CisJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgxKTsKKwl9CisJZWxzZSB7CisJCWlycV9lbmFibGUoYWRhcHRlcik7CisJCWlzc3VlX2NvbW1hbmQoYWRhcHRlcik7CisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qCisgKiBXYWl0IHVudGlsIHRoZSBjb250cm9sbGVyJ3MgbWFpbGJveCBpcyBhdmFpbGFibGUKKyAqLworc3RhdGljIGlubGluZSBpbnQKK21lZ2FfYnVzeXdhaXRfbWJveCAoYWRhcHRlcl90ICphZGFwdGVyKQoreworCWlmIChhZGFwdGVyLT5tYm94LT5tX2luLmJ1c3kpCisJCXJldHVybiBfX21lZ2FfYnVzeXdhaXRfbWJveChhZGFwdGVyKTsKKwlyZXR1cm4gMDsKK30KKworLyoqCisgKiBpc3N1ZV9zY2JfYmxvY2soKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKiBAcmF3X21ib3ggLSB0aGUgbWFpbGJveAorICoKKyAqIElzc3VlIGEgc2NiIGluIHN5bmNocm9ub3VzIGFuZCBub24taW50ZXJydXB0IG1vZGUKKyAqLworc3RhdGljIGludAoraXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXJfdCAqYWRhcHRlciwgdV9jaGFyICpyYXdfbWJveCkKK3sKKwl2b2xhdGlsZSBtYm94NjRfdCAqbWJveDY0ID0gYWRhcHRlci0+bWJveDY0OworCXZvbGF0aWxlIG1ib3hfdCAqbWJveCA9IGFkYXB0ZXItPm1ib3g7CisJdTgJYnl0ZTsKKworCS8qIFdhaXQgdW50aWwgbWFpbGJveCBpcyBmcmVlICovCisJaWYobWVnYV9idXN5d2FpdF9tYm94IChhZGFwdGVyKSkKKwkJZ290byBidWdfYmxvY2tlZF9tYWlsYm94OworCisJLyogQ29weSBtYWlsYm94IGRhdGEgaW50byBob3N0IHN0cnVjdHVyZSAqLworCW1lbWNweSgoY2hhciAqKSBtYm94LCByYXdfbWJveCwgc2l6ZW9mKHN0cnVjdCBtYm94X291dCkpOworCW1ib3gtPm1fb3V0LmNtZGlkID0gMHhGRTsKKwltYm94LT5tX2luLmJ1c3kgPSAxOworCisJc3dpdGNoIChyYXdfbWJveFswXSkgeworCWNhc2UgTUVHQV9NQk9YQ01EX0xSRUFENjQ6CisJY2FzZSBNRUdBX01CT1hDTURfTFdSSVRFNjQ6CisJY2FzZSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDoKKwljYXNlIE1FR0FfTUJPWENNRF9FWFRQVEhSVToKKwkJbWJveDY0LT54ZmVyX3NlZ21lbnRfbG8gPSBtYm94LT5tX291dC54ZmVyYWRkcjsKKwkJbWJveDY0LT54ZmVyX3NlZ21lbnRfaGkgPSAwOworCQltYm94LT5tX291dC54ZmVyYWRkciA9IDB4RkZGRkZGRkY7CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2xvID0gMDsKKwkJbWJveDY0LT54ZmVyX3NlZ21lbnRfaGkgPSAwOworCX0KKworCWlmKCBsaWtlbHkoYWRhcHRlci0+ZmxhZyAmIEJPQVJEX01FTU1BUCkgKSB7CisJCW1ib3gtPm1faW4ucG9sbCA9IDA7CisJCW1ib3gtPm1faW4uYWNrID0gMDsKKwkJbWJveC0+bV9pbi5udW1zdGF0dXMgPSAweEZGOworCQltYm94LT5tX2luLnN0YXR1cyA9IDB4RkY7CisJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgxKTsKKworCQl3aGlsZSgodm9sYXRpbGUgdTgpbWJveC0+bV9pbi5udW1zdGF0dXMgPT0gMHhGRikKKwkJCWNwdV9yZWxheCgpOworCisJCW1ib3gtPm1faW4ubnVtc3RhdHVzID0gMHhGRjsKKworCQl3aGlsZSggKHZvbGF0aWxlIHU4KW1ib3gtPm1faW4ucG9sbCAhPSAweDc3ICkKKwkJCWNwdV9yZWxheCgpOworCisJCW1ib3gtPm1faW4ucG9sbCA9IDA7CisJCW1ib3gtPm1faW4uYWNrID0gMHg3NzsKKworCQlXUklORE9PUihhZGFwdGVyLCBhZGFwdGVyLT5tYm94X2RtYSB8IDB4Mik7CisKKwkJd2hpbGUoUkRJTkRPT1IoYWRhcHRlcikgJiAweDIpCisJCQljcHVfcmVsYXgoKTsKKwl9CisJZWxzZSB7CisJCWlycV9kaXNhYmxlKGFkYXB0ZXIpOworCQlpc3N1ZV9jb21tYW5kKGFkYXB0ZXIpOworCisJCXdoaWxlICghKChieXRlID0gaXJxX3N0YXRlKGFkYXB0ZXIpKSAmIElOVFJfVkFMSUQpKQorCQkJY3B1X3JlbGF4KCk7CisKKwkJc2V0X2lycV9zdGF0ZShhZGFwdGVyLCBieXRlKTsKKwkJaXJxX2VuYWJsZShhZGFwdGVyKTsKKwkJaXJxX2FjayhhZGFwdGVyKTsKKwl9CisKKwlyZXR1cm4gbWJveC0+bV9pbi5zdGF0dXM7CisKK2J1Z19ibG9ja2VkX21haWxib3g6CisJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IEJsb2NrZWQgbWFpbGJveC4uLi4uLiEhXG4iKTsKKwl1ZGVsYXkgKDEwMDApOworCXJldHVybiAtMTsKK30KKworCisvKioKKyAqIG1lZ2FyYWlkX2lzcl9pb21hcHBlZCgpCisgKiBAaXJxIC0gaXJxCisgKiBAZGV2cCAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEByZWdzIC0gdW51c2VkCisgKgorICogSW50ZXJydXB0IHNlcnZpY2Ugcm91dGluZSBmb3IgaW8tbWFwcGVkIGNvbnRyb2xsZXJzLgorICogRmluZCBvdXQgaWYgb3VyIGRldmljZSBpcyBpbnRlcnJ1cHRpbmcuIElmIHllcywgYWNrbm93bGVkZ2UgdGhlIGludGVycnVwdAorICogYW5kIHNlcnZpY2UgdGhlIGNvbXBsZXRlZCBjb21tYW5kcy4KKyAqLworc3RhdGljIGlycXJldHVybl90CittZWdhcmFpZF9pc3JfaW9tYXBwZWQoaW50IGlycSwgdm9pZCAqZGV2cCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCit7CisJYWRhcHRlcl90CSphZGFwdGVyID0gZGV2cDsKKwl1bnNpZ25lZCBsb25nCWZsYWdzOworCXU4CXN0YXR1czsKKwl1OAluc3RhdHVzOworCXU4CWNvbXBsZXRlZFtNQVhfRklSTVdBUkVfU1RBVFVTXTsKKwl1OAlieXRlOworCWludAloYW5kbGVkID0gMDsKKworCisJLyoKKwkgKiBsb29wIHRpbGwgRi9XIGhhcyBtb3JlIGNvbW1hbmRzIGZvciB1cyB0byBjb21wbGV0ZS4KKwkgKi8KKwlzcGluX2xvY2tfaXJxc2F2ZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOworCisJZG8geworCQkvKiBDaGVjayBpZiBhIHZhbGlkIGludGVycnVwdCBpcyBwZW5kaW5nICovCisJCWJ5dGUgPSBpcnFfc3RhdGUoYWRhcHRlcik7CisJCWlmKCAoYnl0ZSAmIFZBTElEX0lOVFJfQllURSkgPT0gMCApIHsKKwkJCS8qCisJCQkgKiBObyBtb3JlIHBlbmRpbmcgY29tbWFuZHMKKwkJCSAqLworCQkJZ290byBvdXRfdW5sb2NrOworCQl9CisJCXNldF9pcnFfc3RhdGUoYWRhcHRlciwgYnl0ZSk7CisKKwkJd2hpbGUoKG5zdGF0dXMgPSAodm9sYXRpbGUgdTgpYWRhcHRlci0+bWJveC0+bV9pbi5udW1zdGF0dXMpCisJCQkJPT0gMHhGRikKKwkJCWNwdV9yZWxheCgpOworCQlhZGFwdGVyLT5tYm94LT5tX2luLm51bXN0YXR1cyA9IDB4RkY7CisKKwkJc3RhdHVzID0gYWRhcHRlci0+bWJveC0+bV9pbi5zdGF0dXM7CisKKwkJLyoKKwkJICogZGVjcmVtZW50IHRoZSBwZW5kaW5nIHF1ZXVlIGNvdW50ZXIKKwkJICovCisJCWF0b21pY19zdWIobnN0YXR1cywgJmFkYXB0ZXItPnBlbmRfY21kcyk7CisKKwkJbWVtY3B5KGNvbXBsZXRlZCwgKHZvaWQgKilhZGFwdGVyLT5tYm94LT5tX2luLmNvbXBsZXRlZCwgCisJCQkJbnN0YXR1cyk7CisKKwkJLyogQWNrbm93bGVkZ2UgaW50ZXJydXB0ICovCisJCWlycV9hY2soYWRhcHRlcik7CisKKwkJbWVnYV9jbWRfZG9uZShhZGFwdGVyLCBjb21wbGV0ZWQsIG5zdGF0dXMsIHN0YXR1cyk7CisKKwkJbWVnYV9ydW5kb25lcShhZGFwdGVyKTsKKworCQloYW5kbGVkID0gMTsKKworCQkvKiBMb29wIHRocm91Z2ggYW55IHBlbmRpbmcgcmVxdWVzdHMgKi8KKwkJaWYoYXRvbWljX3JlYWQoJmFkYXB0ZXItPnF1aWVzY2VudCkgPT0gMCkgeworCQkJbWVnYV9ydW5wZW5kcShhZGFwdGVyKTsKKwkJfQorCisJfSB3aGlsZSgxKTsKKworIG91dF91bmxvY2s6CisKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CisKKwlyZXR1cm4gSVJRX1JFVFZBTChoYW5kbGVkKTsKK30KKworCisvKioKKyAqIG1lZ2FyYWlkX2lzcl9tZW1tYXBwZWQoKQorICogQGlycSAtIGlycQorICogQGRldnAgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKiBAcmVncyAtIHVudXNlZAorICoKKyAqIEludGVycnVwdCBzZXJ2aWNlIHJvdXRpbmUgZm9yIG1lbW9yeS1tYXBwZWQgY29udHJvbGxlcnMuCisgKiBGaW5kIG91dCBpZiBvdXIgZGV2aWNlIGlzIGludGVycnVwdGluZy4gSWYgeWVzLCBhY2tub3dsZWRnZSB0aGUgaW50ZXJydXB0CisgKiBhbmQgc2VydmljZSB0aGUgY29tcGxldGVkIGNvbW1hbmRzLgorICovCitzdGF0aWMgaXJxcmV0dXJuX3QKK21lZ2FyYWlkX2lzcl9tZW1tYXBwZWQoaW50IGlycSwgdm9pZCAqZGV2cCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCit7CisJYWRhcHRlcl90CSphZGFwdGVyID0gZGV2cDsKKwl1bnNpZ25lZCBsb25nCWZsYWdzOworCXU4CXN0YXR1czsKKwl1MzIJZHdvcmQgPSAwOworCXU4CW5zdGF0dXM7CisJdTgJY29tcGxldGVkW01BWF9GSVJNV0FSRV9TVEFUVVNdOworCWludAloYW5kbGVkID0gMDsKKworCisJLyoKKwkgKiBsb29wIHRpbGwgRi9XIGhhcyBtb3JlIGNvbW1hbmRzIGZvciB1cyB0byBjb21wbGV0ZS4KKwkgKi8KKwlzcGluX2xvY2tfaXJxc2F2ZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOworCisJZG8geworCQkvKiBDaGVjayBpZiBhIHZhbGlkIGludGVycnVwdCBpcyBwZW5kaW5nICovCisJCWR3b3JkID0gUkRPVVRET09SKGFkYXB0ZXIpOworCQlpZihkd29yZCAhPSAweDEwMDAxMjM0KSB7CisJCQkvKgorCQkJICogTm8gbW9yZSBwZW5kaW5nIGNvbW1hbmRzCisJCQkgKi8KKwkJCWdvdG8gb3V0X3VubG9jazsKKwkJfQorCQlXUk9VVERPT1IoYWRhcHRlciwgMHgxMDAwMTIzNCk7CisKKwkJd2hpbGUoKG5zdGF0dXMgPSAodm9sYXRpbGUgdTgpYWRhcHRlci0+bWJveC0+bV9pbi5udW1zdGF0dXMpCisJCQkJPT0gMHhGRikgeworCQkJY3B1X3JlbGF4KCk7CisJCX0KKwkJYWRhcHRlci0+bWJveC0+bV9pbi5udW1zdGF0dXMgPSAweEZGOworCisJCXN0YXR1cyA9IGFkYXB0ZXItPm1ib3gtPm1faW4uc3RhdHVzOworCisJCS8qCisJCSAqIGRlY3JlbWVudCB0aGUgcGVuZGluZyBxdWV1ZSBjb3VudGVyCisJCSAqLworCQlhdG9taWNfc3ViKG5zdGF0dXMsICZhZGFwdGVyLT5wZW5kX2NtZHMpOworCisJCW1lbWNweShjb21wbGV0ZWQsICh2b2lkICopYWRhcHRlci0+bWJveC0+bV9pbi5jb21wbGV0ZWQsIAorCQkJCW5zdGF0dXMpOworCisJCS8qIEFja25vd2xlZGdlIGludGVycnVwdCAqLworCQlXUklORE9PUihhZGFwdGVyLCAweDIpOworCisJCWhhbmRsZWQgPSAxOworCisJCXdoaWxlKCBSRElORE9PUihhZGFwdGVyKSAmIDB4MDIgKSBjcHVfcmVsYXgoKTsKKworCQltZWdhX2NtZF9kb25lKGFkYXB0ZXIsIGNvbXBsZXRlZCwgbnN0YXR1cywgc3RhdHVzKTsKKworCQltZWdhX3J1bmRvbmVxKGFkYXB0ZXIpOworCisJCS8qIExvb3AgdGhyb3VnaCBhbnkgcGVuZGluZyByZXF1ZXN0cyAqLworCQlpZihhdG9taWNfcmVhZCgmYWRhcHRlci0+cXVpZXNjZW50KSA9PSAwKSB7CisJCQltZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOworCQl9CisKKwl9IHdoaWxlKDEpOworCisgb3V0X3VubG9jazoKKworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmFkYXB0ZXItPmxvY2ssIGZsYWdzKTsKKworCXJldHVybiBJUlFfUkVUVkFMKGhhbmRsZWQpOworfQorLyoqCisgKiBtZWdhX2NtZF9kb25lKCkKKyAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICogQGNvbXBsZXRlZCAtIGFycmF5IG9mIGlkcyBvZiBjb21wbGV0ZWQgY29tbWFuZHMKKyAqIEBuc3RhdHVzIC0gbnVtYmVyIG9mIGNvbXBsZXRlZCBjb21tYW5kcworICogQHN0YXR1cyAtIHN0YXR1cyBvZiB0aGUgbGFzdCBjb21tYW5kIGNvbXBsZXRlZAorICoKKyAqIENvbXBsZXRlIHRoZSBjb21hbW5kcyBhbmQgY2FsbCB0aGUgc2NzaSBtaWQtbGF5ZXIgY2FsbGJhY2sgaG9va3MuCisgKi8KK3N0YXRpYyB2b2lkCittZWdhX2NtZF9kb25lKGFkYXB0ZXJfdCAqYWRhcHRlciwgdTggY29tcGxldGVkW10sIGludCBuc3RhdHVzLCBpbnQgc3RhdHVzKQoreworCW1lZ2FfZXh0X3Bhc3N0aHJ1CSplcHRocnUgPSBOVUxMOworCXN0cnVjdCBzY2F0dGVybGlzdAkqc2dsOworCVNjc2lfQ21uZAkqY21kID0gTlVMTDsKKwltZWdhX3Bhc3N0aHJ1CSpwdGhydSA9IE5VTEw7CisJbWJveF90CSptYm94ID0gTlVMTDsKKwl1OAljOworCXNjYl90CSpzY2I7CisJaW50CWlzbG9naWNhbDsKKwlpbnQJY21kaWQ7CisJaW50CWk7CisKKwkvKgorCSAqIGZvciBhbGwgdGhlIGNvbW1hbmRzIGNvbXBsZXRlZCwgY2FsbCB0aGUgbWlkLWxheWVyIGNhbGxiYWNrIHJvdXRpbmUKKwkgKiBhbmQgZnJlZSB0aGUgc2NiLgorCSAqLworCWZvciggaSA9IDA7IGkgPCBuc3RhdHVzOyBpKysgKSB7CisKKwkJY21kaWQgPSBjb21wbGV0ZWRbaV07CisKKwkJaWYoIGNtZGlkID09IENNRElEX0lOVF9DTURTICkgeyAvKiBpbnRlcm5hbCBjb21tYW5kICovCisJCQlzY2IgPSAmYWRhcHRlci0+aW50X3NjYjsKKwkJCWNtZCA9IHNjYi0+Y21kOworCQkJbWJveCA9IChtYm94X3QgKilzY2ItPnJhd19tYm94OworCisJCQkvKgorCQkJICogSW50ZXJuYWwgY29tbWFuZCBpbnRlcmZhY2UgZG8gbm90IGZpcmUgdGhlIGV4dGVuZGVkCisJCQkgKiBwYXNzdGhydSBvciA2NC1iaXQgcGFzc3RocnUKKwkJCSAqLworCQkJcHRocnUgPSBzY2ItPnB0aHJ1OworCisJCX0KKwkJZWxzZSB7CisJCQlzY2IgPSAmYWRhcHRlci0+c2NiX2xpc3RbY21kaWRdOworCisJCQkvKgorCQkJICogTWFrZSBzdXJlIGYvdyBoYXMgY29tcGxldGVkIGEgdmFsaWQgY29tbWFuZAorCQkJICovCisJCQlpZiggIShzY2ItPnN0YXRlICYgU0NCX0lTU1VFRCkgfHwgc2NiLT5jbWQgPT0gTlVMTCApIHsKKwkJCQlwcmludGsoS0VSTl9DUklUCisJCQkJCSJtZWdhcmFpZDogaW52YWxpZCBjb21tYW5kICIpOworCQkJCXByaW50aygiSWQgJWQsIHNjYi0+c3RhdGU6JXgsIHNjc2kgY21kOiVwXG4iLAorCQkJCQljbWRpZCwgc2NiLT5zdGF0ZSwgc2NiLT5jbWQpOworCisJCQkJY29udGludWU7CisJCQl9CisKKwkJCS8qCisJCQkgKiBXYXMgYSBhYm9ydCBpc3N1ZWQgZm9yIHRoaXMgY29tbWFuZAorCQkJICovCisJCQlpZiggc2NiLT5zdGF0ZSAmIFNDQl9BQk9SVCApIHsKKworCQkJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCQkibWVnYXJhaWQ6IGFib3J0ZWQgY21kICVseFsleF0gY29tcGxldGUuXG4iLAorCQkJCQlzY2ItPmNtZC0+c2VyaWFsX251bWJlciwgc2NiLT5pZHgpOworCisJCQkJc2NiLT5jbWQtPnJlc3VsdCA9IChESURfQUJPUlQgPDwgMTYpOworCisJCQkJbGlzdF9hZGRfdGFpbChTQ1NJX0xJU1Qoc2NiLT5jbWQpLAorCQkJCQkJJmFkYXB0ZXItPmNvbXBsZXRlZF9saXN0KTsKKworCQkJCW1lZ2FfZnJlZV9zY2IoYWRhcHRlciwgc2NiKTsKKworCQkJCWNvbnRpbnVlOworCQkJfQorCisJCQkvKgorCQkJICogV2FzIGEgcmVzZXQgaXNzdWVkIGZvciB0aGlzIGNvbW1hbmQKKwkJCSAqLworCQkJaWYoIHNjYi0+c3RhdGUgJiBTQ0JfUkVTRVQgKSB7CisKKwkJCQlwcmludGsoS0VSTl9XQVJOSU5HCisJCQkJIm1lZ2FyYWlkOiByZXNldCBjbWQgJWx4WyV4XSBjb21wbGV0ZS5cbiIsCisJCQkJCXNjYi0+Y21kLT5zZXJpYWxfbnVtYmVyLCBzY2ItPmlkeCk7CisKKwkJCQlzY2ItPmNtZC0+cmVzdWx0ID0gKERJRF9SRVNFVCA8PCAxNik7CisKKwkJCQlsaXN0X2FkZF90YWlsKFNDU0lfTElTVChzY2ItPmNtZCksCisJCQkJCQkmYWRhcHRlci0+Y29tcGxldGVkX2xpc3QpOworCisJCQkJbWVnYV9mcmVlX3NjYiAoYWRhcHRlciwgc2NiKTsKKworCQkJCWNvbnRpbnVlOworCQkJfQorCisJCQljbWQgPSBzY2ItPmNtZDsKKwkJCXB0aHJ1ID0gc2NiLT5wdGhydTsKKwkJCWVwdGhydSA9IHNjYi0+ZXB0aHJ1OworCQkJbWJveCA9IChtYm94X3QgKilzY2ItPnJhd19tYm94OworCisjaWYgTUVHQV9IQVZFX1NUQVRTCisJCQl7CisKKwkJCWludAlsb2dkcnYgPSBtYm94LT5tX291dC5sb2dkcnY7CisKKwkJCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+Y2hhbm5lbF07CisJCQkvKgorCQkJICogTWFpbnRhaW4gYW4gZXJyb3IgY291bnRlciBmb3IgdGhlIGxvZ2ljYWwgZHJpdmUuCisJCQkgKiBTb21lIGFwcGxpY2F0aW9uIGxpa2UgU05NUCBhZ2VudCBuZWVkIHN1Y2gKKwkJCSAqIHN0YXRpc3RpY3MKKwkJCSAqLworCQkJaWYoIHN0YXR1cyAmJiBpc2xvZ2ljYWwgJiYgKGNtZC0+Y21uZFswXSA9PSBSRUFEXzYgfHwKKwkJCQkJCWNtZC0+Y21uZFswXSA9PSBSRUFEXzEwIHx8CisJCQkJCQljbWQtPmNtbmRbMF0gPT0gUkVBRF8xMikpIHsKKwkJCQkvKgorCQkJCSAqIExvZ2ljYWwgZHJpdmUgbnVtYmVyIGluY3JlYXNlcyBieSAweDgwIHdoZW4KKwkJCQkgKiBhIGxvZ2ljYWwgZHJpdmUgaXMgZGVsZXRlZAorCQkJCSAqLworCQkJCWFkYXB0ZXItPnJkX2Vycm9yc1tsb2dkcnYlMHg4MF0rKzsKKwkJCX0KKworCQkJaWYoIHN0YXR1cyAmJiBpc2xvZ2ljYWwgJiYgKGNtZC0+Y21uZFswXSA9PSBXUklURV82IHx8CisJCQkJCQljbWQtPmNtbmRbMF0gPT0gV1JJVEVfMTAgfHwKKwkJCQkJCWNtZC0+Y21uZFswXSA9PSBXUklURV8xMikpIHsKKwkJCQkvKgorCQkJCSAqIExvZ2ljYWwgZHJpdmUgbnVtYmVyIGluY3JlYXNlcyBieSAweDgwIHdoZW4KKwkJCQkgKiBhIGxvZ2ljYWwgZHJpdmUgaXMgZGVsZXRlZAorCQkJCSAqLworCQkJCWFkYXB0ZXItPndyX2Vycm9yc1tsb2dkcnYlMHg4MF0rKzsKKwkJCX0KKworCQkJfQorI2VuZGlmCisJCX0KKworCQkvKgorCQkgKiBEbyBub3QgcmV0dXJuIHRoZSBwcmVzZW5jZSBvZiBoYXJkIGRpc2sgb24gdGhlIGNoYW5uZWwgc28sCisJCSAqIGlucXVpcnkgc2VudCwgYW5kIHJldHVybmVkIGRhdGE9PWhhcmQgZGlzayBvciByZW1vdmFibGUKKwkJICogaGFyZCBkaXNrIGFuZCBub3QgbG9naWNhbCwgcmVxdWVzdCBzaG91bGQgcmV0dXJuIGZhaWx1cmUhIC0KKwkJICogUEoKKwkJICovCisJCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+ZGV2aWNlLT5jaGFubmVsXTsKKwkJaWYoIGNtZC0+Y21uZFswXSA9PSBJTlFVSVJZICYmICFpc2xvZ2ljYWwgKSB7CisKKwkJCWlmKCBjbWQtPnVzZV9zZyApIHsKKwkJCQlzZ2wgPSAoc3RydWN0IHNjYXR0ZXJsaXN0ICopCisJCQkJCWNtZC0+cmVxdWVzdF9idWZmZXI7CisKKwkJCQlpZiggc2dsLT5wYWdlICkgeworCQkJCQljID0gKih1bnNpZ25lZCBjaGFyICopCisJCQkJCXBhZ2VfYWRkcmVzcygoJnNnbFswXSktPnBhZ2UpICsKKwkJCQkJKCZzZ2xbMF0pLT5vZmZzZXQ7IAorCQkJCX0KKwkJCQllbHNlIHsKKwkJCQkJcHJpbnRrKEtFUk5fV0FSTklORworCQkJCQkJIm1lZ2FyYWlkOiBpbnZhbGlkIHNnLlxuIik7CisJCQkJCWMgPSAwOworCQkJCX0KKwkJCX0KKwkJCWVsc2UgeworCQkJCWMgPSAqKHU4ICopY21kLT5yZXF1ZXN0X2J1ZmZlcjsKKwkJCX0KKworCQkJaWYoSVNfUkFJRF9DSChhZGFwdGVyLCBjbWQtPmRldmljZS0+Y2hhbm5lbCkgJiYKKwkJCQkJKChjICYgMHgxRiApID09IFRZUEVfRElTSykpIHsKKwkJCQlzdGF0dXMgPSAweEYwOworCQkJfQorCQl9CisKKwkJLyogY2xlYXIgcmVzdWx0OyBvdGhlcndpc2UsIHN1Y2Nlc3MgcmV0dXJucyBjb3JydXB0IHZhbHVlICovCisJCWNtZC0+cmVzdWx0ID0gMDsKKworCQkvKiBDb252ZXJ0IE1lZ2FSQUlEIHN0YXR1cyB0byBMaW51eCBlcnJvciBjb2RlICovCisJCXN3aXRjaCAoc3RhdHVzKSB7CisJCWNhc2UgMHgwMDoJLyogU1VDQ0VTUyAsIGkuZS4gU0NTSV9TVEFUVVNfR09PRCAqLworCQkJY21kLT5yZXN1bHQgfD0gKERJRF9PSyA8PCAxNik7CisJCQlicmVhazsKKworCQljYXNlIDB4MDI6CS8qIEVSUk9SX0FCT1JURUQsIGkuZS4KKwkJCQkgICBTQ1NJX1NUQVRVU19DSEVDS19DT05ESVRJT04gKi8KKworCQkJLyogc2V0IHNlbnNlX2J1ZmZlciBhbmQgcmVzdWx0IGZpZWxkcyAqLworCQkJaWYoIG1ib3gtPm1fb3V0LmNtZCA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlUgfHwKKwkJCQltYm94LT5tX291dC5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVNjQgKSB7CisKKwkJCQltZW1jcHkoY21kLT5zZW5zZV9idWZmZXIsIHB0aHJ1LT5yZXFzZW5zZWFyZWEsCisJCQkJCQkxNCk7CisKKwkJCQljbWQtPnJlc3VsdCA9IChEUklWRVJfU0VOU0UgPDwgMjQpIHwKKwkJCQkJKERJRF9PSyA8PCAxNikgfAorCQkJCQkoQ0hFQ0tfQ09ORElUSU9OIDw8IDEpOworCQkJfQorCQkJZWxzZSB7CisJCQkJaWYgKG1ib3gtPm1fb3V0LmNtZCA9PSBNRUdBX01CT1hDTURfRVhUUFRIUlUpIHsKKworCQkJCQltZW1jcHkoY21kLT5zZW5zZV9idWZmZXIsCisJCQkJCQllcHRocnUtPnJlcXNlbnNlYXJlYSwgMTQpOworCisJCQkJCWNtZC0+cmVzdWx0ID0gKERSSVZFUl9TRU5TRSA8PCAyNCkgfAorCQkJCQkJKERJRF9PSyA8PCAxNikgfAorCQkJCQkJKENIRUNLX0NPTkRJVElPTiA8PCAxKTsKKwkJCQl9IGVsc2UgeworCQkJCQljbWQtPnNlbnNlX2J1ZmZlclswXSA9IDB4NzA7CisJCQkJCWNtZC0+c2Vuc2VfYnVmZmVyWzJdID0gQUJPUlRFRF9DT01NQU5EOworCQkJCQljbWQtPnJlc3VsdCB8PSAoQ0hFQ0tfQ09ORElUSU9OIDw8IDEpOworCQkJCX0KKwkJCX0KKwkJCWJyZWFrOworCisJCWNhc2UgMHgwODoJLyogRVJSX0RFU1RfRFJJVkVfRkFJTEVELCBpLmUuCisJCQkJICAgU0NTSV9TVEFUVVNfQlVTWSAqLworCQkJY21kLT5yZXN1bHQgfD0gKERJRF9CVVNfQlVTWSA8PCAxNikgfCBzdGF0dXM7CisJCQlicmVhazsKKworCQlkZWZhdWx0OgorI2lmIE1FR0FfSEFWRV9DTFVTVEVSSU5HCisJCQkvKgorCQkJICogSWYgVEVTVF9VTklUX1JFQURZIGZhaWxzLCB3ZSBrbm93CisJCQkgKiBNRUdBX1JFU0VSVkFUSU9OX1NUQVRVUyBmYWlsZWQKKwkJCSAqLworCQkJaWYoIGNtZC0+Y21uZFswXSA9PSBURVNUX1VOSVRfUkVBRFkgKSB7CisJCQkJY21kLT5yZXN1bHQgfD0gKERJRF9FUlJPUiA8PCAxNikgfAorCQkJCQkoUkVTRVJWQVRJT05fQ09ORkxJQ1QgPDwgMSk7CisJCQl9CisJCQllbHNlCisJCQkvKgorCQkJICogRXJyb3IgY29kZSByZXR1cm5lZCBpcyAxIGlmIFJlc2VydmUgb3IgUmVsZWFzZQorCQkJICogZmFpbGVkIG9yIHRoZSBpbnB1dCBwYXJhbWV0ZXIgaXMgaW52YWxpZAorCQkJICovCisJCQlpZiggc3RhdHVzID09IDEgJiYKKwkJCQkoY21kLT5jbW5kWzBdID09IFJFU0VSVkUgfHwKKwkJCQkJIGNtZC0+Y21uZFswXSA9PSBSRUxFQVNFKSApIHsKKworCQkJCWNtZC0+cmVzdWx0IHw9IChESURfRVJST1IgPDwgMTYpIHwKKwkJCQkJKFJFU0VSVkFUSU9OX0NPTkZMSUNUIDw8IDEpOworCQkJfQorCQkJZWxzZQorI2VuZGlmCisJCQkJY21kLT5yZXN1bHQgfD0gKERJRF9CQURfVEFSR0VUIDw8IDE2KXxzdGF0dXM7CisJCX0KKworCQkvKgorCQkgKiBPbmx5IGZyZWUgU0NCcyBmb3IgdGhlIGNvbW1hbmRzIGNvbWluZyBkb3duIGZyb20gdGhlCisJCSAqIG1pZC1sYXllciwgbm90IGZvciB3aGljaCB3ZXJlIGlzc3VlZCBpbnRlcm5hbGx5CisJCSAqCisJCSAqIEZvciBpbnRlcm5hbCBjb21tYW5kLCByZXN0b3JlIHRoZSBzdGF0dXMgcmV0dXJuZWQgYnkgdGhlCisJCSAqIGZpcm13YXJlIHNvIHRoYXQgdXNlciBjYW4gaW50ZXJwcmV0IGl0LgorCQkgKi8KKwkJaWYoIGNtZGlkID09IENNRElEX0lOVF9DTURTICkgeyAvKiBpbnRlcm5hbCBjb21tYW5kICovCisJCQljbWQtPnJlc3VsdCA9IHN0YXR1czsKKworCQkJLyoKKwkJCSAqIFJlbW92ZSB0aGUgaW50ZXJuYWwgY29tbWFuZCBmcm9tIHRoZSBwZW5kaW5nIGxpc3QKKwkJCSAqLworCQkJbGlzdF9kZWxfaW5pdCgmc2NiLT5saXN0KTsKKwkJCXNjYi0+c3RhdGUgPSBTQ0JfRlJFRTsKKwkJfQorCQllbHNlIHsKKwkJCW1lZ2FfZnJlZV9zY2IoYWRhcHRlciwgc2NiKTsKKwkJfQorCisJCS8qIEFkZCBTY3NpX0NvbW1hbmQgdG8gZW5kIG9mIGNvbXBsZXRlZCBxdWV1ZSAqLworCQlsaXN0X2FkZF90YWlsKFNDU0lfTElTVChjbWQpLCAmYWRhcHRlci0+Y29tcGxldGVkX2xpc3QpOworCX0KK30KKworCisvKgorICogbWVnYV9ydW5wZW5kcSgpCisgKgorICogUnVuIHRocm91Z2ggdGhlIGxpc3Qgb2YgY29tcGxldGVkIHJlcXVlc3RzIGFuZCBmaW5pc2ggaXQKKyAqLworc3RhdGljIHZvaWQKK21lZ2FfcnVuZG9uZXEgKGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwlTY3NpX0NtbmQgKmNtZDsKKwlzdHJ1Y3QgbGlzdF9oZWFkICpwb3M7CisKKwlsaXN0X2Zvcl9lYWNoKHBvcywgJmFkYXB0ZXItPmNvbXBsZXRlZF9saXN0KSB7CisKKwkJU2NzaV9Qb2ludGVyKiBzcG9zID0gKFNjc2lfUG9pbnRlciAqKXBvczsKKworCQljbWQgPSBsaXN0X2VudHJ5KHNwb3MsIFNjc2lfQ21uZCwgU0NwKTsKKwkJY21kLT5zY3NpX2RvbmUoY21kKTsKKwl9CisKKwlJTklUX0xJU1RfSEVBRCgmYWRhcHRlci0+Y29tcGxldGVkX2xpc3QpOworfQorCisKKy8qCisgKiBGcmVlIGEgU0NCIHN0cnVjdHVyZQorICogTm90ZTogV2UgYXNzdW1lIHRoZSBzY3NpIGNvbW1hbmRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNjYiBpcyBub3QgZnJlZSB5ZXQuCisgKi8KK3N0YXRpYyB2b2lkCittZWdhX2ZyZWVfc2NiKGFkYXB0ZXJfdCAqYWRhcHRlciwgc2NiX3QgKnNjYikKK3sKKwlzd2l0Y2goIHNjYi0+ZG1hX3R5cGUgKSB7CisKKwljYXNlIE1FR0FfRE1BX1RZUEVfTk9ORToKKwkJYnJlYWs7CisKKwljYXNlIE1FR0FfQlVMS19EQVRBOgorCQlwY2lfdW5tYXBfcGFnZShhZGFwdGVyLT5kZXYsIHNjYi0+ZG1hX2hfYnVsa2RhdGEsCisJCQlzY2ItPmNtZC0+cmVxdWVzdF9idWZmbGVuLCBzY2ItPmRtYV9kaXJlY3Rpb24pOworCQlicmVhazsKKworCWNhc2UgTUVHQV9TR0xJU1Q6CisJCXBjaV91bm1hcF9zZyhhZGFwdGVyLT5kZXYsIHNjYi0+Y21kLT5yZXF1ZXN0X2J1ZmZlciwKKwkJCXNjYi0+Y21kLT51c2Vfc2csIHNjYi0+ZG1hX2RpcmVjdGlvbik7CisJCWJyZWFrOworCisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorCisJLyoKKwkgKiBSZW1vdmUgZnJvbSB0aGUgcGVuZGluZyBsaXN0CisJICovCisJbGlzdF9kZWxfaW5pdCgmc2NiLT5saXN0KTsKKworCS8qIExpbmsgdGhlIHNjYiBiYWNrIGludG8gZnJlZSBsaXN0ICovCisJc2NiLT5zdGF0ZSA9IFNDQl9GUkVFOworCXNjYi0+Y21kID0gTlVMTDsKKworCWxpc3RfYWRkKCZzY2ItPmxpc3QsICZhZGFwdGVyLT5mcmVlX2xpc3QpOworfQorCisKK3N0YXRpYyBpbnQKK19fbWVnYV9idXN5d2FpdF9tYm94IChhZGFwdGVyX3QgKmFkYXB0ZXIpCit7CisJdm9sYXRpbGUgbWJveF90ICptYm94ID0gYWRhcHRlci0+bWJveDsKKwlsb25nIGNvdW50ZXI7CisKKwlmb3IgKGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwMDA7IGNvdW50ZXIrKykgeworCQlpZiAoIW1ib3gtPm1faW4uYnVzeSkKKwkJCXJldHVybiAwOworCQl1ZGVsYXkoMTAwKTsgeWllbGQoKTsKKwl9CisJcmV0dXJuIC0xOwkJLyogZ2l2ZSB1cCBhZnRlciAxIHNlY29uZCAqLworfQorCisvKgorICogQ29waWVzIGRhdGEgdG8gU0dMSVNUCisgKiBOb3RlOiBGb3IgNjQgYml0IGNhcmRzLCB3ZSBuZWVkIGEgbWluaW11bSBvZiBvbmUgU0cgZWxlbWVudCBmb3IgcmVhZC93cml0ZQorICovCitzdGF0aWMgaW50CittZWdhX2J1aWxkX3NnbGlzdChhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIHUzMiAqYnVmLCB1MzIgKmxlbikKK3sKKwlzdHJ1Y3Qgc2NhdHRlcmxpc3QJKnNnbDsKKwlzdHJ1Y3QgcGFnZQkqcGFnZTsKKwl1bnNpZ25lZCBsb25nCW9mZnNldDsKKwlTY3NpX0NtbmQJKmNtZDsKKwlpbnQJc2djbnQ7CisJaW50CWlkeDsKKworCWNtZCA9IHNjYi0+Y21kOworCisJLyogU2NhdHRlci1nYXRoZXIgbm90IHVzZWQgKi8KKwlpZiggIWNtZC0+dXNlX3NnICkgeworCisJCXBhZ2UgPSB2aXJ0X3RvX3BhZ2UoY21kLT5yZXF1ZXN0X2J1ZmZlcik7CisJCW9mZnNldCA9IG9mZnNldF9pbl9wYWdlKGNtZC0+cmVxdWVzdF9idWZmZXIpOworCisJCXNjYi0+ZG1hX2hfYnVsa2RhdGEgPSBwY2lfbWFwX3BhZ2UoYWRhcHRlci0+ZGV2LAorCQkJCQkJICBwYWdlLCBvZmZzZXQsCisJCQkJCQkgIGNtZC0+cmVxdWVzdF9idWZmbGVuLAorCQkJCQkJICBzY2ItPmRtYV9kaXJlY3Rpb24pOworCQlzY2ItPmRtYV90eXBlID0gTUVHQV9CVUxLX0RBVEE7CisKKwkJLyoKKwkJICogV2UgbmVlZCB0byBoYW5kbGUgc3BlY2lhbCA2NC1iaXQgY29tbWFuZHMgdGhhdCBuZWVkIGEKKwkJICogbWluaW11bSBvZiAxIFNHCisJCSAqLworCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CisJCQlzY2ItPnNnbDY0WzBdLmFkZHJlc3MgPSBzY2ItPmRtYV9oX2J1bGtkYXRhOworCQkJc2NiLT5zZ2w2NFswXS5sZW5ndGggPSBjbWQtPnJlcXVlc3RfYnVmZmxlbjsKKwkJCSpidWYgPSAodTMyKXNjYi0+c2dsX2RtYV9hZGRyOworCQkJKmxlbiA9ICh1MzIpY21kLT5yZXF1ZXN0X2J1ZmZsZW47CisJCQlyZXR1cm4gMTsKKwkJfQorCQllbHNlIHsKKwkJCSpidWYgPSAodTMyKXNjYi0+ZG1hX2hfYnVsa2RhdGE7CisJCQkqbGVuID0gKHUzMiljbWQtPnJlcXVlc3RfYnVmZmxlbjsKKwkJfQorCQlyZXR1cm4gMDsKKwl9CisKKwlzZ2wgPSAoc3RydWN0IHNjYXR0ZXJsaXN0ICopY21kLT5yZXF1ZXN0X2J1ZmZlcjsKKworCS8qCisJICogQ29weSBTY2F0dGVyLUdhdGhlciBsaXN0IGluZm8gaW50byBjb250cm9sbGVyIHN0cnVjdHVyZS4KKwkgKgorCSAqIFRoZSBudW1iZXIgb2Ygc2cgZWxlbWVudHMgcmV0dXJuZWQgbXVzdCBub3QgZXhjZWVkIG91ciBsaW1pdAorCSAqLworCXNnY250ID0gcGNpX21hcF9zZyhhZGFwdGVyLT5kZXYsIHNnbCwgY21kLT51c2Vfc2csCisJCQlzY2ItPmRtYV9kaXJlY3Rpb24pOworCisJc2NiLT5kbWFfdHlwZSA9IE1FR0FfU0dMSVNUOworCisJaWYoIHNnY250ID4gYWRhcHRlci0+c2dsZW4gKSBCVUcoKTsKKworCWZvciggaWR4ID0gMDsgaWR4IDwgc2djbnQ7IGlkeCsrLCBzZ2wrKyApIHsKKworCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CisJCQlzY2ItPnNnbDY0W2lkeF0uYWRkcmVzcyA9IHNnX2RtYV9hZGRyZXNzKHNnbCk7CisJCQlzY2ItPnNnbDY0W2lkeF0ubGVuZ3RoID0gc2dfZG1hX2xlbihzZ2wpOworCQl9CisJCWVsc2UgeworCQkJc2NiLT5zZ2xbaWR4XS5hZGRyZXNzID0gc2dfZG1hX2FkZHJlc3Moc2dsKTsKKwkJCXNjYi0+c2dsW2lkeF0ubGVuZ3RoID0gc2dfZG1hX2xlbihzZ2wpOworCQl9CisJfQorCisJLyogUmVzZXQgcG9pbnRlciBhbmQgbGVuZ3RoIGZpZWxkcyAqLworCSpidWYgPSBzY2ItPnNnbF9kbWFfYWRkcjsKKworCS8qCisJICogRm9yIHBhc3N0aHJ1IGNvbW1hbmQsIGRhdGF4ZmVybGVuIG11c3QgYmUgc2V0LCBldmVuIGZvciBjb21tYW5kcworCSAqIHdpdGggYSBzZyBsaXN0CisJICovCisJKmxlbiA9ICh1MzIpY21kLT5yZXF1ZXN0X2J1ZmZsZW47CisKKwkvKiBSZXR1cm4gY291bnQgb2YgU0cgcmVxdWVzdHMgKi8KKwlyZXR1cm4gc2djbnQ7Cit9CisKKworLyoKKyAqIG1lZ2FfOF90b180MGxkKCkKKyAqCisgKiB0YWtlcyBhbGwgaW5mbyBpbiBBZGFwdGVySW5xdWlyeSBzdHJ1Y3R1cmUgYW5kIHB1dHMgaXQgaW50byBQcm9kdWN0SW5mbyBhbmQKKyAqIEVucXVpcnkzIHN0cnVjdHVyZXMgZm9yIGxhdGVyIHVzZQorICovCitzdGF0aWMgdm9pZAorbWVnYV84X3RvXzQwbGQobXJhaWRfaW5xdWlyeSAqaW5xdWlyeSwgbWVnYV9pbnF1aXJ5MyAqZW5xdWlyeTMsCisJCW1lZ2FfcHJvZHVjdF9pbmZvICpwcm9kdWN0X2luZm8pCit7CisJaW50IGk7CisKKwlwcm9kdWN0X2luZm8tPm1heF9jb21tYW5kcyA9IGlucXVpcnktPmFkYXB0ZXJfaW5mby5tYXhfY29tbWFuZHM7CisJZW5xdWlyeTMtPnJlYnVpbGRfcmF0ZSA9IGlucXVpcnktPmFkYXB0ZXJfaW5mby5yZWJ1aWxkX3JhdGU7CisJcHJvZHVjdF9pbmZvLT5uY2hhbm5lbHMgPSBpbnF1aXJ5LT5hZGFwdGVyX2luZm8ubmNoYW5uZWxzOworCisJZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgeworCQlwcm9kdWN0X2luZm8tPmZ3X3ZlcnNpb25baV0gPQorCQkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmZ3X3ZlcnNpb25baV07CisKKwkJcHJvZHVjdF9pbmZvLT5iaW9zX3ZlcnNpb25baV0gPQorCQkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmJpb3NfdmVyc2lvbltpXTsKKwl9CisJZW5xdWlyeTMtPmNhY2hlX2ZsdXNoX2ludGVydmFsID0KKwkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmNhY2hlX2ZsdXNoX2ludGVydmFsOworCisJcHJvZHVjdF9pbmZvLT5kcmFtX3NpemUgPSBpbnF1aXJ5LT5hZGFwdGVyX2luZm8uZHJhbV9zaXplOworCisJZW5xdWlyeTMtPm51bV9sZHJ2ID0gaW5xdWlyeS0+bG9nZHJ2X2luZm8ubnVtX2xkcnY7CisKKwlmb3IgKGkgPSAwOyBpIDwgTUFYX0xPR0lDQUxfRFJJVkVTXzhMRDsgaSsrKSB7CisJCWVucXVpcnkzLT5sZHJ2X3NpemVbaV0gPSBpbnF1aXJ5LT5sb2dkcnZfaW5mby5sZHJ2X3NpemVbaV07CisJCWVucXVpcnkzLT5sZHJ2X3Byb3BbaV0gPSBpbnF1aXJ5LT5sb2dkcnZfaW5mby5sZHJ2X3Byb3BbaV07CisJCWVucXVpcnkzLT5sZHJ2X3N0YXRlW2ldID0gaW5xdWlyeS0+bG9nZHJ2X2luZm8ubGRydl9zdGF0ZVtpXTsKKwl9CisKKwlmb3IgKGkgPSAwOyBpIDwgKE1BWF9QSFlTSUNBTF9EUklWRVMpOyBpKyspCisJCWVucXVpcnkzLT5wZHJ2X3N0YXRlW2ldID0gaW5xdWlyeS0+cGRydl9pbmZvLnBkcnZfc3RhdGVbaV07Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZAorbWVnYV9mcmVlX3NnbChhZGFwdGVyX3QgKmFkYXB0ZXIpCit7CisJc2NiX3QJKnNjYjsKKwlpbnQJaTsKKworCWZvcihpID0gMDsgaSA8IGFkYXB0ZXItPm1heF9jbWRzOyBpKyspIHsKKworCQlzY2IgPSAmYWRhcHRlci0+c2NiX2xpc3RbaV07CisKKwkJaWYoIHNjYi0+c2dsNjQgKSB7CisJCQlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKKwkJCQlzaXplb2YobWVnYV9zZ2w2NCkgKiBhZGFwdGVyLT5zZ2xlbiwKKwkJCQlzY2ItPnNnbDY0LAorCQkJCXNjYi0+c2dsX2RtYV9hZGRyKTsKKworCQkJc2NiLT5zZ2w2NCA9IE5VTEw7CisJCX0KKworCQlpZiggc2NiLT5wdGhydSApIHsKKwkJCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksCisJCQkJc2NiLT5wdGhydSwgc2NiLT5wdGhydV9kbWFfYWRkcik7CisKKwkJCXNjYi0+cHRocnUgPSBOVUxMOworCQl9CisKKwkJaWYoIHNjYi0+ZXB0aHJ1ICkgeworCQkJcGNpX2ZyZWVfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsCisJCQkJc2l6ZW9mKG1lZ2FfZXh0X3Bhc3N0aHJ1KSwKKwkJCQlzY2ItPmVwdGhydSwgc2NiLT5lcHRocnVfZG1hX2FkZHIpOworCisJCQlzY2ItPmVwdGhydSA9IE5VTEw7CisJCX0KKworCX0KK30KKworCisvKgorICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHRoZSBjYXJkL2RyaXZlcgorICovCitjb25zdCBjaGFyICoKK21lZ2FyYWlkX2luZm8oc3RydWN0IFNjc2lfSG9zdCAqaG9zdCkKK3sKKwlzdGF0aWMgY2hhciBidWZmZXJbNTEyXTsKKwlhZGFwdGVyX3QgKmFkYXB0ZXI7CisKKwlhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOworCisJc3ByaW50ZiAoYnVmZmVyLAorCQkgIkxTSSBMb2dpYyBNZWdhUkFJRCAlcyAlZCBjb21tYW5kcyAlZCB0YXJncyAlZCBjaGFucyAlZCBsdW5zIiwKKwkJIGFkYXB0ZXItPmZ3X3ZlcnNpb24sIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5tYXhfY29tbWFuZHMsCisJCSBhZGFwdGVyLT5ob3N0LT5tYXhfaWQsIGFkYXB0ZXItPmhvc3QtPm1heF9jaGFubmVsLAorCQkgYWRhcHRlci0+aG9zdC0+bWF4X2x1bik7CisJcmV0dXJuIGJ1ZmZlcjsKK30KKworLyoKKyAqIEFib3J0IGEgcHJldmlvdXMgU0NTSSByZXF1ZXN0LiBPbmx5IGNvbW1hbmRzIG9uIHRoZSBwZW5kaW5nIGxpc3QgY2FuIGJlCisgKiBhYm9ydGVkLiBBbGwgdGhlIGNvbW1hbmRzIGlzc3VlZCB0byB0aGUgRi9XIG11c3QgY29tcGxldGUuCisgKi8KK3N0YXRpYyBpbnQKK21lZ2FyYWlkX2Fib3J0KFNjc2lfQ21uZCAqY21kKQoreworCWFkYXB0ZXJfdAkqYWRhcHRlcjsKKwlpbnQJCXJ2YWw7CisKKwlhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWNtZC0+ZGV2aWNlLT5ob3N0LT5ob3N0ZGF0YTsKKworCXJ2YWwgPSAgbWVnYXJhaWRfYWJvcnRfYW5kX3Jlc2V0KGFkYXB0ZXIsIGNtZCwgU0NCX0FCT1JUKTsKKworCS8qCisJICogVGhpcyBpcyByZXF1aXJlZCBoZXJlIHRvIGNvbXBsZXRlIGFueSBjb21wbGV0ZWQgcmVxdWVzdHMKKwkgKiB0byBiZSBjb21tdW5pY2F0ZWQgb3ZlciB0byB0aGUgbWlkIGxheWVyLgorCSAqLworCW1lZ2FfcnVuZG9uZXEoYWRhcHRlcik7CisKKwlyZXR1cm4gcnZhbDsKK30KKworCitzdGF0aWMgaW50CittZWdhcmFpZF9yZXNldChTY3NpX0NtbmQgKmNtZCkKK3sKKwlhZGFwdGVyX3QJKmFkYXB0ZXI7CisJbWVnYWNtZF90CW1jOworCWludAkJcnZhbDsKKworCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopY21kLT5kZXZpY2UtPmhvc3QtPmhvc3RkYXRhOworCisjaWYgTUVHQV9IQVZFX0NMVVNURVJJTkcKKwltYy5jbWQgPSBNRUdBX0NMVVNURVJfQ01EOworCW1jLm9wY29kZSA9IE1FR0FfUkVTRVRfUkVTRVJWQVRJT05TOworCisJc3Bpbl91bmxvY2tfaXJxKCZhZGFwdGVyLT5sb2NrKTsKKwlpZiggbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpICE9IDAgKSB7CisJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCQkibWVnYXJhaWQ6IHJlc2VydmF0aW9uIHJlc2V0IGZhaWxlZC5cbiIpOworCX0KKwllbHNlIHsKKwkJcHJpbnRrKEtFUk5fSU5GTyAibWVnYXJhaWQ6IHJlc2VydmF0aW9uIHJlc2V0LlxuIik7CisJfQorCXNwaW5fbG9ja19pcnEoJmFkYXB0ZXItPmxvY2spOworI2VuZGlmCisKKwlydmFsID0gIG1lZ2FyYWlkX2Fib3J0X2FuZF9yZXNldChhZGFwdGVyLCBjbWQsIFNDQl9SRVNFVCk7CisKKwkvKgorCSAqIFRoaXMgaXMgcmVxdWlyZWQgaGVyZSB0byBjb21wbGV0ZSBhbnkgY29tcGxldGVkIHJlcXVlc3RzCisJICogdG8gYmUgY29tbXVuaWNhdGVkIG92ZXIgdG8gdGhlIG1pZCBsYXllci4KKwkgKi8KKwltZWdhX3J1bmRvbmVxKGFkYXB0ZXIpOworCisJcmV0dXJuIHJ2YWw7Cit9CisKKworCisvKioKKyAqIG1lZ2FyYWlkX2Fib3J0X2FuZF9yZXNldCgpCisgKiBAYWRhcHRlciAtIG1lZ2FyYWlkIHNvZnQgc3RhdGUKKyAqIEBjbWQgLSBzY3NpIGNvbW1hbmQgdG8gYmUgYWJvcnRlZCBvciByZXNldAorICogQGFvciAtIGFib3J0IG9yIHJlc2V0IGZsYWcKKyAqCisgKiBUcnkgdG8gbG9jYXRlIHRoZSBzY3NpIGNvbW1hbmQgaW4gdGhlIHBlbmRpbmcgcXVldWUuIElmIGZvdW5kIGFuZCBpcyBub3QKKyAqIGlzc3VlZCB0byB0aGUgY29udHJvbGxlciwgYWJvcnQvcmVzZXQgaXQuIE90aGVyd2lzZSByZXR1cm4gZmFpbHVyZQorICovCitzdGF0aWMgaW50CittZWdhcmFpZF9hYm9ydF9hbmRfcmVzZXQoYWRhcHRlcl90ICphZGFwdGVyLCBTY3NpX0NtbmQgKmNtZCwgaW50IGFvcikKK3sKKwlzdHJ1Y3QgbGlzdF9oZWFkCSpwb3MsICpuZXh0OworCXNjYl90CQkJKnNjYjsKKworCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiAlcy0lbHggY21kPSV4IDxjPSVkIHQ9JWQgbD0lZD5cbiIsCisJICAgICAoYW9yID09IFNDQl9BQk9SVCk/ICJBQk9SVElORyI6IlJFU0VUIiwgY21kLT5zZXJpYWxfbnVtYmVyLAorCSAgICAgY21kLT5jbW5kWzBdLCBjbWQtPmRldmljZS0+Y2hhbm5lbCwgCisJICAgICBjbWQtPmRldmljZS0+aWQsIGNtZC0+ZGV2aWNlLT5sdW4pOworCisJaWYobGlzdF9lbXB0eSgmYWRhcHRlci0+cGVuZGluZ19saXN0KSkKKwkJcmV0dXJuIEZBTFNFOworCisJbGlzdF9mb3JfZWFjaF9zYWZlKHBvcywgbmV4dCwgJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCkgeworCisJCXNjYiA9IGxpc3RfZW50cnkocG9zLCBzY2JfdCwgbGlzdCk7CisKKwkJaWYgKHNjYi0+Y21kID09IGNtZCkgeyAvKiBGb3VuZCBjb21tYW5kICovCisKKwkJCXNjYi0+c3RhdGUgfD0gYW9yOworCisJCQkvKgorCQkJICogQ2hlY2sgaWYgdGhpcyBjb21tYW5kIGhhcyBmaXJtYXJlIG93ZW5lcnNoaXAuIElmCisJCQkgKiB5ZXMsIHdlIGNhbm5vdCByZXNldCB0aGlzIGNvbW1hbmQuIFdoZW5ldmVyLCBmL3cKKwkJCSAqIGNvbXBsZXRlcyB0aGlzIGNvbW1hbmQsIHdlIHdpbGwgcmV0dXJuIGFwcHJvcHJpYXRlCisJCQkgKiBzdGF0dXMgZnJvbSBJU1IuCisJCQkgKi8KKwkJCWlmKCBzY2ItPnN0YXRlICYgU0NCX0lTU1VFRCApIHsKKworCQkJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCQkJIm1lZ2FyYWlkOiAlcy0lbHhbJXhdLCBmdyBvd25lci5cbiIsCisJCQkJCShhb3I9PVNDQl9BQk9SVCkgPyAiQUJPUlRJTkciOiJSRVNFVCIsCisJCQkJCWNtZC0+c2VyaWFsX251bWJlciwgc2NiLT5pZHgpOworCisJCQkJcmV0dXJuIEZBTFNFOworCQkJfQorCQkJZWxzZSB7CisKKwkJCQkvKgorCQkJCSAqIE5vdCB5ZXQgaXNzdWVkISBSZW1vdmUgZnJvbSB0aGUgcGVuZGluZworCQkJCSAqIGxpc3QKKwkJCQkgKi8KKwkJCQlwcmludGsoS0VSTl9XQVJOSU5HCisJCQkJCSJtZWdhcmFpZDogJXMtJWx4WyV4XSwgZHJpdmVyIG93bmVyLlxuIiwKKwkJCQkJKGFvcj09U0NCX0FCT1JUKSA/ICJBQk9SVElORyI6IlJFU0VUIiwKKwkJCQkJY21kLT5zZXJpYWxfbnVtYmVyLCBzY2ItPmlkeCk7CisKKwkJCQltZWdhX2ZyZWVfc2NiKGFkYXB0ZXIsIHNjYik7CisKKwkJCQlpZiggYW9yID09IFNDQl9BQk9SVCApIHsKKwkJCQkJY21kLT5yZXN1bHQgPSAoRElEX0FCT1JUIDw8IDE2KTsKKwkJCQl9CisJCQkJZWxzZSB7CisJCQkJCWNtZC0+cmVzdWx0ID0gKERJRF9SRVNFVCA8PCAxNik7CisJCQkJfQorCisJCQkJbGlzdF9hZGRfdGFpbChTQ1NJX0xJU1QoY21kKSwKKwkJCQkJCSZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7CisKKwkJCQlyZXR1cm4gVFJVRTsKKwkJCX0KKwkJfQorCX0KKworCXJldHVybiBGQUxTRTsKK30KKworc3RhdGljIGlubGluZSBpbnQKK21ha2VfbG9jYWxfcGRldihhZGFwdGVyX3QgKmFkYXB0ZXIsIHN0cnVjdCBwY2lfZGV2ICoqcGRldikKK3sKKwkqcGRldiA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBwY2lfZGV2KSwgR0ZQX0tFUk5FTCk7CisKKwlpZiggKnBkZXYgPT0gTlVMTCApIHJldHVybiAtMTsKKworCW1lbWNweSgqcGRldiwgYWRhcHRlci0+ZGV2LCBzaXplb2Yoc3RydWN0IHBjaV9kZXYpKTsKKworCWlmKCBwY2lfc2V0X2RtYV9tYXNrKCpwZGV2LCAweGZmZmZmZmZmKSAhPSAwICkgeworCQlrZnJlZSgqcGRldik7CisJCXJldHVybiAtMTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGlubGluZSB2b2lkCitmcmVlX2xvY2FsX3BkZXYoc3RydWN0IHBjaV9kZXYgKnBkZXYpCit7CisJa2ZyZWUocGRldik7Cit9CisKKy8qKgorICogbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KCkKKyAqIEBkbWFfaGFuZGxlIC0gaGFuZGxlIHJldHVybmVkIGZvciBkbWEgYWRkcmVzcworICogQHBkZXYgLSBoYW5kbGUgdG8gcGNpIGRldmljZQorICoKKyAqIGFsbG9jYXRlcyBtZW1vcnkgZm9yIGlucXVpcnkgc3RydWN0dXJlCisgKi8KK3N0YXRpYyBpbmxpbmUgdm9pZCAqCittZWdhX2FsbG9jYXRlX2lucXVpcnkoZG1hX2FkZHJfdCAqZG1hX2hhbmRsZSwgc3RydWN0IHBjaV9kZXYgKnBkZXYpCit7CisJcmV0dXJuIHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsIHNpemVvZihtZWdhX2lucXVpcnkzKSwgZG1hX2hhbmRsZSk7Cit9CisKKworc3RhdGljIGlubGluZSB2b2lkCittZWdhX2ZyZWVfaW5xdWlyeSh2b2lkICppbnF1aXJ5LCBkbWFfYWRkcl90IGRtYV9oYW5kbGUsIHN0cnVjdCBwY2lfZGV2ICpwZGV2KQoreworCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgc2l6ZW9mKG1lZ2FfaW5xdWlyeTMpLCBpbnF1aXJ5LCBkbWFfaGFuZGxlKTsKK30KKworCisjaWZkZWYgQ09ORklHX1BST0NfRlMKKy8qIEZvbGxvd2luZyBjb2RlIGhhbmRsZXMgL3Byb2MgZnMgICovCisKKyNkZWZpbmUgQ1JFQVRFX1JFQURfUFJPQyhzdHJpbmcsIGZ1bmMpCWNyZWF0ZV9wcm9jX3JlYWRfZW50cnkoc3RyaW5nLAlcCisJCQkJCVNfSVJVU1IgfCBTX0lGUkVHLAkJXAorCQkJCQljb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5LAlcCisJCQkJCWZ1bmMsIGFkYXB0ZXIpCisKKy8qKgorICogbWVnYV9jcmVhdGVfcHJvY19lbnRyeSgpCisgKiBAaW5kZXggLSBpbmRleCBpbiBzb2Z0IHN0YXRlIGFycmF5CisgKiBAcGFyZW50IC0gcGFyZW50IG5vZGUgZm9yIHRoaXMgL3Byb2MgZW50cnkKKyAqCisgKiBDcmVhdGVzIC9wcm9jIGVudHJpZXMgZm9yIG91ciBjb250cm9sbGVycy4KKyAqLworc3RhdGljIHZvaWQKK21lZ2FfY3JlYXRlX3Byb2NfZW50cnkoaW50IGluZGV4LCBzdHJ1Y3QgcHJvY19kaXJfZW50cnkgKnBhcmVudCkKK3sKKwlzdHJ1Y3QgcHJvY19kaXJfZW50cnkJKmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkgPSBOVUxMOworCXU4CQlzdHJpbmdbNjRdID0geyAwIH07CisJYWRhcHRlcl90CSphZGFwdGVyID0gaGJhX3NvZnRfc3RhdGVbaW5kZXhdOworCisJc3ByaW50ZihzdHJpbmcsICJoYmElZCIsIGFkYXB0ZXItPmhvc3QtPmhvc3Rfbm8pOworCisJY29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSA9CisJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkgPSBwcm9jX21rZGlyKHN0cmluZywgcGFyZW50KTsKKworCWlmKCFjb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KSB7CisJCXByaW50ayhLRVJOX1dBUk5JTkcgIlxubWVnYXJhaWQ6IHByb2NfbWtkaXIgZmFpbGVkXG4iKTsKKwkJcmV0dXJuOworCX0KKwlhZGFwdGVyLT5wcm9jX3JlYWQgPSBDUkVBVEVfUkVBRF9QUk9DKCJjb25maWciLCBwcm9jX3JlYWRfY29uZmlnKTsKKwlhZGFwdGVyLT5wcm9jX3N0YXQgPSBDUkVBVEVfUkVBRF9QUk9DKCJzdGF0IiwgcHJvY19yZWFkX3N0YXQpOworCWFkYXB0ZXItPnByb2NfbWJveCA9IENSRUFURV9SRUFEX1BST0MoIm1haWxib3giLCBwcm9jX3JlYWRfbWJveCk7CisjaWYgTUVHQV9IQVZFX0VOSF9QUk9DCisJYWRhcHRlci0+cHJvY19yciA9IENSRUFURV9SRUFEX1BST0MoInJlYnVpbGQtcmF0ZSIsIHByb2NfcmVidWlsZF9yYXRlKTsKKwlhZGFwdGVyLT5wcm9jX2JhdHRlcnkgPSBDUkVBVEVfUkVBRF9QUk9DKCJiYXR0ZXJ5LXN0YXR1cyIsCisJCQlwcm9jX2JhdHRlcnkpOworCisJLyoKKwkgKiBEaXNwbGF5IGVhY2ggcGh5c2ljYWwgZHJpdmUgb24gaXRzIGNoYW5uZWwKKwkgKi8KKwlhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzBdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDAiLAorCQkJCQlwcm9jX3BkcnZfY2gwKTsKKwlhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzFdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDEiLAorCQkJCQlwcm9jX3BkcnZfY2gxKTsKKwlhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzJdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDIiLAorCQkJCQlwcm9jX3BkcnZfY2gyKTsKKwlhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzNdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDMiLAorCQkJCQlwcm9jX3BkcnZfY2gzKTsKKworCS8qCisJICogRGlzcGxheSBhIHNldCBvZiB1cCB0byAxMCBsb2dpY2FsIGRyaXZlIHRocm91Z2ggZWFjaCBvZiBmb2xsb3dpbmcKKwkgKiAvcHJvYyBlbnRyaWVzCisJICovCisJYWRhcHRlci0+cHJvY19yZHJ2c3RhdFswXSA9IENSRUFURV9SRUFEX1BST0MoInJhaWRkcml2ZXMtMC05IiwKKwkJCQkJcHJvY19yZHJ2XzEwKTsKKwlhZGFwdGVyLT5wcm9jX3JkcnZzdGF0WzFdID0gQ1JFQVRFX1JFQURfUFJPQygicmFpZGRyaXZlcy0xMC0xOSIsCisJCQkJCXByb2NfcmRydl8yMCk7CisJYWRhcHRlci0+cHJvY19yZHJ2c3RhdFsyXSA9IENSRUFURV9SRUFEX1BST0MoInJhaWRkcml2ZXMtMjAtMjkiLAorCQkJCQlwcm9jX3JkcnZfMzApOworCWFkYXB0ZXItPnByb2NfcmRydnN0YXRbM10gPSBDUkVBVEVfUkVBRF9QUk9DKCJyYWlkZHJpdmVzLTMwLTM5IiwKKwkJCQkJcHJvY19yZHJ2XzQwKTsKKyNlbmRpZgorfQorCisKKy8qKgorICogcHJvY19yZWFkX2NvbmZpZygpCisgKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgorICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQorICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAorICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRGlzcGxheSBjb25maWd1cmF0aW9uIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb250cm9sbGVyLgorICovCitzdGF0aWMgaW50Citwcm9jX3JlYWRfY29uZmlnKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAorCQl2b2lkICpkYXRhKQoreworCisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisJaW50IGxlbiA9IDA7CisKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVzIiwgTUVHQVJBSURfVkVSU0lPTik7CisKKwlpZihhZGFwdGVyLT5wcm9kdWN0X2luZm8ucHJvZHVjdF9uYW1lWzBdKQorCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVzXG4iLAorCQkJCWFkYXB0ZXItPnByb2R1Y3RfaW5mby5wcm9kdWN0X25hbWUpOworCisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJDb250cm9sbGVyIFR5cGU6ICIpOworCisJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF9NRU1NQVAgKSB7CisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAorCQkJIjQzOC80NjYvNDY3LzQ3MS80OTMvNTE4LzUyMC81MzEvNTMyXG4iKTsKKwl9CisJZWxzZSB7CisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAorCQkJIjQxOC80MjgvNDM0XG4iKTsKKwl9CisKKwlpZihhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgeworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKKwkJCQkiQ29udHJvbGxlciBTdXBwb3J0cyA0MCBMb2dpY2FsIERyaXZlc1xuIik7CisJfQorCisJaWYoYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzY0QklUKSB7CisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAorCQkiQ29udHJvbGxlciBjYXBhYmxlIG9mIDY0LWJpdCBtZW1vcnkgYWRkcmVzc2luZ1xuIik7CisJfQorCWlmKCBhZGFwdGVyLT5oYXNfNjRiaXRfYWRkciApIHsKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCisJCQkiQ29udHJvbGxlciB1c2luZyA2NC1iaXQgbWVtb3J5IGFkZHJlc3NpbmdcbiIpOworCX0KKwllbHNlIHsKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCisJCQkiQ29udHJvbGxlciBpcyBub3QgdXNpbmcgNjQtYml0IG1lbW9yeSBhZGRyZXNzaW5nXG4iKTsKKwl9CisKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkJhc2UgPSAlMDhseCwgSXJxID0gJWQsICIsIGFkYXB0ZXItPmJhc2UsCisJCQlhZGFwdGVyLT5ob3N0LT5pcnEpOworCisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJMb2dpY2FsIERyaXZlcyA9ICVkLCBDaGFubmVscyA9ICVkXG4iLAorCQkJYWRhcHRlci0+bnVtbGRydiwgYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVscyk7CisKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlZlcnNpb24gPSVzOiVzLCBEUkFNID0gJWRNYlxuIiwKKwkJCWFkYXB0ZXItPmZ3X3ZlcnNpb24sIGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwKKwkJCWFkYXB0ZXItPnByb2R1Y3RfaW5mby5kcmFtX3NpemUpOworCisJbGVuICs9IHNwcmludGYocGFnZStsZW4sCisJCSJDb250cm9sbGVyIFF1ZXVlIERlcHRoID0gJWQsIERyaXZlciBRdWV1ZSBEZXB0aCA9ICVkXG4iLAorCQlhZGFwdGVyLT5wcm9kdWN0X2luZm8ubWF4X2NvbW1hbmRzLCBhZGFwdGVyLT5tYXhfY21kcyk7CisKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN1cHBvcnRfZXh0X2NkYiAgICA9ICVkXG4iLAorCQkJYWRhcHRlci0+c3VwcG9ydF9leHRfY2RiKTsKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN1cHBvcnRfcmFuZG9tX2RlbCA9ICVkXG4iLAorCQkJYWRhcHRlci0+c3VwcG9ydF9yYW5kb21fZGVsKTsKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgImJvb3RfbGRydl9lbmFibGVkICA9ICVkXG4iLAorCQkJYWRhcHRlci0+Ym9vdF9sZHJ2X2VuYWJsZWQpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiYm9vdF9sZHJ2ICAgICAgICAgID0gJWRcbiIsCisJCQlhZGFwdGVyLT5ib290X2xkcnYpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiYm9vdF9wZHJ2X2VuYWJsZWQgID0gJWRcbiIsCisJCQlhZGFwdGVyLT5ib290X3BkcnZfZW5hYmxlZCk7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJib290X3BkcnZfY2ggICAgICAgPSAlZFxuIiwKKwkJCWFkYXB0ZXItPmJvb3RfcGRydl9jaCk7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJib290X3BkcnZfdGd0ICAgICAgPSAlZFxuIiwKKwkJCWFkYXB0ZXItPmJvb3RfcGRydl90Z3QpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAicXVpZXNjZW50ICAgICAgICAgID0gJWRcbiIsCisJCQlhdG9taWNfcmVhZCgmYWRhcHRlci0+cXVpZXNjZW50KSk7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJoYXNfY2x1c3RlciAgICAgICAgPSAlZFxuIiwKKwkJCWFkYXB0ZXItPmhhc19jbHVzdGVyKTsKKworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiXG5Nb2R1bGUgUGFyYW1ldGVyczpcbiIpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAibWF4X2NtZF9wZXJfbHVuICAgID0gJWRcbiIsCisJCQltYXhfY21kX3Blcl9sdW4pOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAibWF4X3NlY3RvcnNfcGVyX2lvID0gJWRcbiIsCisJCQltYXhfc2VjdG9yc19wZXJfaW8pOworCisJKmVvZiA9IDE7CisKKwlyZXR1cm4gbGVuOworfQorCisKKworLyoqCisgKiBwcm9jX3JlYWRfc3RhdCgpCisgKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgorICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQorICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAorICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRGlhcGxheSBzdGF0aXN0aWNhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgSS9PIGFjdGl2aXR5LgorICovCitzdGF0aWMgaW50Citwcm9jX3JlYWRfc3RhdChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKKwkJdm9pZCAqZGF0YSkKK3sKKwlhZGFwdGVyX3QJKmFkYXB0ZXI7CisJaW50CWxlbjsKKwlpbnQJaTsKKworCWkgPSAwOwkvKiBhdm9pZCBjb21waWxhdGlvbiB3YXJuaW5ncyAqLworCWxlbiA9IDA7CisJYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOworCisJbGVuID0gc3ByaW50ZihwYWdlLCAiU3RhdGlzdGljYWwgSW5mb3JtYXRpb24gZm9yIHRoaXMgY29udHJvbGxlclxuIik7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJwZW5kX2NtZHMgPSAlZFxuIiwKKwkJCWF0b21pY19yZWFkKCZhZGFwdGVyLT5wZW5kX2NtZHMpKTsKKyNpZiBNRUdBX0hBVkVfU1RBVFMKKwlmb3IoaSA9IDA7IGkgPCBhZGFwdGVyLT5udW1sZHJ2OyBpKyspIHsKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJMb2dpY2FsIERyaXZlICVkOlxuIiwgaSk7CisKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCisJCQkiXHRSZWFkcyBJc3N1ZWQgPSAlbHUsIFdyaXRlcyBJc3N1ZWQgPSAlbHVcbiIsCisJCQlhZGFwdGVyLT5ucmVhZHNbaV0sIGFkYXB0ZXItPm53cml0ZXNbaV0pOworCisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAorCQkJIlx0U2VjdG9ycyBSZWFkID0gJWx1LCBTZWN0b3JzIFdyaXR0ZW4gPSAlbHVcbiIsCisJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tpXSwgYWRhcHRlci0+bndyaXRlYmxvY2tzW2ldKTsKKworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKKwkJCSJcdFJlYWQgZXJyb3JzID0gJWx1LCBXcml0ZSBlcnJvcnMgPSAlbHVcblxuIiwKKwkJCWFkYXB0ZXItPnJkX2Vycm9yc1tpXSwgYWRhcHRlci0+d3JfZXJyb3JzW2ldKTsKKwl9CisjZWxzZQorCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAorCQkJIklPIGFuZCBlcnJvciBjb3VudGVycyBub3QgY29tcGlsZWQgaW4gZHJpdmVyLlxuIik7CisjZW5kaWYKKworCSplb2YgPSAxOworCisJcmV0dXJuIGxlbjsKK30KKworCisvKioKKyAqIHByb2NfcmVhZF9tYm94KCkKKyAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCisgKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCisgKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCisgKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBEaXNwbGF5IG1haWxib3ggaW5mb3JtYXRpb24gZm9yIHRoZSBsYXN0IGNvbW1hbmQgaXNzdWVkLiBUaGlzIGluZm9ybWF0aW9uCisgKiBpcyBnb29kIGZvciBkZWJ1Z2dpbmcuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcmVhZF9tYm94KGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAorCQl2b2lkICpkYXRhKQoreworCisJYWRhcHRlcl90CSphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisJdm9sYXRpbGUgbWJveF90CSptYm94ID0gYWRhcHRlci0+bWJveDsKKwlpbnQJbGVuID0gMDsKKworCWxlbiA9IHNwcmludGYocGFnZSwgIkNvbnRlbnRzIG9mIE1haWwgQm94IFN0cnVjdHVyZVxuIik7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIEZ3IENvbW1hbmQgICA9IDB4JTAyeFxuIiwgCisJCQltYm94LT5tX291dC5jbWQpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBDbWQgU2VxdWVuY2UgPSAweCUwMnhcbiIsIAorCQkJbWJveC0+bV9vdXQuY21kaWQpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBObyBvZiBTZWN0b3JzPSAlMDRkXG4iLCAKKwkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnMpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBMQkEgICAgICAgICAgPSAweCUwMnhcbiIsIAorCQkJbWJveC0+bV9vdXQubGJhKTsKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgRFRBICAgICAgICAgID0gMHglMDh4XG4iLCAKKwkJCW1ib3gtPm1fb3V0LnhmZXJhZGRyKTsKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgTG9naWNhbCBEcml2ZT0gMHglMDJ4XG4iLCAKKwkJCW1ib3gtPm1fb3V0LmxvZ2Rydik7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIE5vIG9mIFNHIEVsbXQ9IDB4JTAyeFxuIiwKKwkJCW1ib3gtPm1fb3V0Lm51bXNnZWxlbWVudHMpOworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBCdXN5ICAgICAgICAgPSAlMDF4XG4iLCAKKwkJCW1ib3gtPm1faW4uYnVzeSk7CisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIFN0YXR1cyAgICAgICA9IDB4JTAyeFxuIiwgCisJCQltYm94LT5tX2luLnN0YXR1cyk7CisKKwkqZW9mID0gMTsKKworCXJldHVybiBsZW47Cit9CisKKworLyoqCisgKiBwcm9jX3JlYnVpbGRfcmF0ZSgpCisgKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgorICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQorICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAorICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRGlzcGxheSBjdXJyZW50IHJlYnVpbGQgcmF0ZQorICovCitzdGF0aWMgaW50Citwcm9jX3JlYnVpbGRfcmF0ZShjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKKwkJdm9pZCAqZGF0YSkKK3sKKwlhZGFwdGVyX3QJKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKKwlkbWFfYWRkcl90CWRtYV9oYW5kbGU7CisJY2FkZHJfdAkJaW5xdWlyeTsKKwlzdHJ1Y3QgcGNpX2RldgkqcGRldjsKKwlpbnQJbGVuID0gMDsKKworCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSB7CisJCSplb2YgPSAxOworCQlyZXR1cm4gbGVuOworCX0KKworCWlmKCAoaW5xdWlyeSA9IG1lZ2FfYWxsb2NhdGVfaW5xdWlyeSgmZG1hX2hhbmRsZSwgcGRldikpID09IE5VTEwgKSB7CisJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKKwkJKmVvZiA9IDE7CisJCXJldHVybiBsZW47CisJfQorCisJaWYoIG1lZ2FfYWRhcGlucShhZGFwdGVyLCBkbWFfaGFuZGxlKSAhPSAwICkgeworCisJCWxlbiA9IHNwcmludGYocGFnZSwgIkFkYXB0ZXIgaW5xdWlyeSBmYWlsZWQuXG4iKTsKKworCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogaW5xdWlyeSBmYWlsZWQuXG4iKTsKKworCQltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKKworCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CisKKwkJKmVvZiA9IDE7CisKKwkJcmV0dXJuIGxlbjsKKwl9CisKKwlpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CisJCWxlbiA9IHNwcmludGYocGFnZSwgIlJlYnVpbGQgUmF0ZTogWyVkJSVdXG4iLAorCQkJKChtZWdhX2lucXVpcnkzICopaW5xdWlyeSktPnJlYnVpbGRfcmF0ZSk7CisJfQorCWVsc2UgeworCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJSZWJ1aWxkIFJhdGU6IFslZCUlXVxuIiwKKwkJCSgobXJhaWRfZXh0X2lucXVpcnkgKikKKwkJCWlucXVpcnkpLT5yYWlkX2lucS5hZGFwdGVyX2luZm8ucmVidWlsZF9yYXRlKTsKKwl9CisKKworCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOworCisJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJKmVvZiA9IDE7CisKKwlyZXR1cm4gbGVuOworfQorCisKKy8qKgorICogcHJvY19iYXR0ZXJ5KCkKKyAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCisgKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCisgKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCisgKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBEaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBiYXR0ZXJ5IG1vZHVsZSBvbiB0aGUgY29udHJvbGxlci4KKyAqLworc3RhdGljIGludAorcHJvY19iYXR0ZXJ5KGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAorCQl2b2lkICpkYXRhKQoreworCWFkYXB0ZXJfdAkqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOworCWRtYV9hZGRyX3QJZG1hX2hhbmRsZTsKKwljYWRkcl90CQlpbnF1aXJ5OworCXN0cnVjdCBwY2lfZGV2CSpwZGV2OworCXU4CWJhdHRlcnlfc3RhdHVzID0gMDsKKwljaGFyCXN0clsyNTZdOworCWludAlsZW4gPSAwOworCisJaWYoIG1ha2VfbG9jYWxfcGRldihhZGFwdGVyLCAmcGRldikgIT0gMCApIHsKKwkJKmVvZiA9IDE7CisJCXJldHVybiBsZW47CisJfQorCisJaWYoIChpbnF1aXJ5ID0gbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KCZkbWFfaGFuZGxlLCBwZGV2KSkgPT0gTlVMTCApIHsKKwkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCQkqZW9mID0gMTsKKwkJcmV0dXJuIGxlbjsKKwl9CisKKwlpZiggbWVnYV9hZGFwaW5xKGFkYXB0ZXIsIGRtYV9oYW5kbGUpICE9IDAgKSB7CisKKwkJbGVuID0gc3ByaW50ZihwYWdlLCAiQWRhcHRlciBpbnF1aXJ5IGZhaWxlZC5cbiIpOworCisJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBpbnF1aXJ5IGZhaWxlZC5cbiIpOworCisJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOworCisJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKKworCQkqZW9mID0gMTsKKworCQlyZXR1cm4gbGVuOworCX0KKworCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKKwkJYmF0dGVyeV9zdGF0dXMgPSAoKG1lZ2FfaW5xdWlyeTMgKilpbnF1aXJ5KS0+YmF0dGVyeV9zdGF0dXM7CisJfQorCWVsc2UgeworCQliYXR0ZXJ5X3N0YXR1cyA9ICgobXJhaWRfZXh0X2lucXVpcnkgKilpbnF1aXJ5KS0+CisJCQlyYWlkX2lucS5hZGFwdGVyX2luZm8uYmF0dGVyeV9zdGF0dXM7CisJfQorCisJLyoKKwkgKiBEZWNvZGUgdGhlIGJhdHRlcnkgc3RhdHVzCisJICovCisJc3ByaW50ZihzdHIsICJCYXR0ZXJ5IFN0YXR1czpbJWRdIiwgYmF0dGVyeV9zdGF0dXMpOworCisJaWYoYmF0dGVyeV9zdGF0dXMgPT0gTUVHQV9CQVRUX0NIQVJHRV9ET05FKQorCQlzdHJjYXQoc3RyLCAiIENoYXJnZSBEb25lIik7CisKKwlpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9NT0RVTEVfTUlTU0lORykKKwkJc3RyY2F0KHN0ciwgIiBNb2R1bGUgTWlzc2luZyIpOworCQorCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX0xPV19WT0xUQUdFKQorCQlzdHJjYXQoc3RyLCAiIExvdyBWb2x0YWdlIik7CisJCisJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfVEVNUF9ISUdIKQorCQlzdHJjYXQoc3RyLCAiIFRlbXBlcmF0dXJlIEhpZ2giKTsKKwkKKwlpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9QQUNLX01JU1NJTkcpCisJCXN0cmNhdChzdHIsICIgUGFjayBNaXNzaW5nIik7CisJCisJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfQ0hBUkdFX0lOUFJPRykKKwkJc3RyY2F0KHN0ciwgIiBDaGFyZ2UgSW4tcHJvZ3Jlc3MiKTsKKwkKKwlpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9DSEFSR0VfRkFJTCkKKwkJc3RyY2F0KHN0ciwgIiBDaGFyZ2UgRmFpbCIpOworCQorCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX0NZQ0xFU19FWENFRURFRCkKKwkJc3RyY2F0KHN0ciwgIiBDeWNsZXMgRXhjZWVkZWQiKTsKKworCWxlbiA9IHNwcmludGYocGFnZSwgIiVzXG4iLCBzdHIpOworCisKKwltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKKworCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKKworCSplb2YgPSAxOworCisJcmV0dXJuIGxlbjsKK30KKworCisvKioKKyAqIHByb2NfcGRydl9jaDAoKQorICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KKyAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKKyAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKKyAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDAuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcGRydl9jaDAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCisJCXZvaWQgKmRhdGEpCit7CisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisKKwkqZW9mID0gMTsKKworCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDApKTsKK30KKworCisvKioKKyAqIHByb2NfcGRydl9jaDEoKQorICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KKyAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKKyAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKKyAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDEuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcGRydl9jaDEoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCisJCXZvaWQgKmRhdGEpCit7CisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisKKwkqZW9mID0gMTsKKworCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDEpKTsKK30KKworCisvKioKKyAqIHByb2NfcGRydl9jaDIoKQorICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KKyAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKKyAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKKyAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDIuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcGRydl9jaDIoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCisJCXZvaWQgKmRhdGEpCit7CisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisKKwkqZW9mID0gMTsKKworCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDIpKTsKK30KKworCisvKioKKyAqIHByb2NfcGRydl9jaDMoKQorICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KKyAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKKyAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKKyAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDMuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcGRydl9jaDMoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCisJCXZvaWQgKmRhdGEpCit7CisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisKKwkqZW9mID0gMTsKKworCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDMpKTsKK30KKworCisvKioKKyAqIHByb2NfcGRydigpCisgKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGh5c2ljYWwgZHJpdmVzLgorICovCitzdGF0aWMgaW50Citwcm9jX3BkcnYoYWRhcHRlcl90ICphZGFwdGVyLCBjaGFyICpwYWdlLCBpbnQgY2hhbm5lbCkKK3sKKwlkbWFfYWRkcl90CWRtYV9oYW5kbGU7CisJY2hhcgkJKnNjc2lfaW5xOworCWRtYV9hZGRyX3QJc2NzaV9pbnFfZG1hX2hhbmRsZTsKKwljYWRkcl90CQlpbnF1aXJ5OworCXN0cnVjdCBwY2lfZGV2CSpwZGV2OworCXU4CSpwZHJ2X3N0YXRlOworCXU4CXN0YXRlOworCWludAl0Z3Q7CisJaW50CW1heF9jaGFubmVsczsKKwlpbnQJbGVuID0gMDsKKwljaGFyCXN0cls4MF07CisJaW50CWk7CisKKwlpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkgeworCQlyZXR1cm4gbGVuOworCX0KKworCWlmKCAoaW5xdWlyeSA9IG1lZ2FfYWxsb2NhdGVfaW5xdWlyeSgmZG1hX2hhbmRsZSwgcGRldikpID09IE5VTEwgKSB7CisJCWdvdG8gZnJlZV9wZGV2OworCX0KKworCWlmKCBtZWdhX2FkYXBpbnEoYWRhcHRlciwgZG1hX2hhbmRsZSkgIT0gMCApIHsKKwkJbGVuID0gc3ByaW50ZihwYWdlLCAiQWRhcHRlciBpbnF1aXJ5IGZhaWxlZC5cbiIpOworCisJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBpbnF1aXJ5IGZhaWxlZC5cbiIpOworCisJCWdvdG8gZnJlZV9pbnF1aXJ5OworCX0KKworCisJc2NzaV9pbnEgPSBwY2lfYWxsb2NfY29uc2lzdGVudChwZGV2LCAyNTYsICZzY3NpX2lucV9kbWFfaGFuZGxlKTsKKworCWlmKCBzY3NpX2lucSA9PSBOVUxMICkgeworCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJtZW1vcnkgbm90IGF2YWlsYWJsZSBmb3Igc2NzaSBpbnEuXG4iKTsKKworCQlnb3RvIGZyZWVfaW5xdWlyeTsKKwl9CisKKwlpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CisJCXBkcnZfc3RhdGUgPSAoKG1lZ2FfaW5xdWlyeTMgKilpbnF1aXJ5KS0+cGRydl9zdGF0ZTsKKwl9CisJZWxzZSB7CisJCXBkcnZfc3RhdGUgPSAoKG1yYWlkX2V4dF9pbnF1aXJ5ICopaW5xdWlyeSktPgorCQkJcmFpZF9pbnEucGRydl9pbmZvLnBkcnZfc3RhdGU7CisJfQorCisJbWF4X2NoYW5uZWxzID0gYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsKKworCWlmKCBjaGFubmVsID49IG1heF9jaGFubmVscyApIHsKKwkJZ290byBmcmVlX3BjaTsKKwl9CisKKwlmb3IoIHRndCA9IDA7IHRndCA8PSBNQVhfVEFSR0VUOyB0Z3QrKyApIHsKKworCQlpID0gY2hhbm5lbCoxNiArIHRndDsKKworCQlzdGF0ZSA9ICoocGRydl9zdGF0ZSArIGkpOworCisJCXN3aXRjaCggc3RhdGUgJiAweDBGICkgeworCisJCWNhc2UgUERSVl9PTkxJTkU6CisJCQlzcHJpbnRmKHN0ciwKKwkJCSJDaGFubmVsOiUyZCBJZDolMmQgU3RhdGU6IE9ubGluZSIsCisJCQkJY2hhbm5lbCwgdGd0KTsKKwkJCWJyZWFrOworCisJCWNhc2UgUERSVl9GQUlMRUQ6CisJCQlzcHJpbnRmKHN0ciwKKwkJCSJDaGFubmVsOiUyZCBJZDolMmQgU3RhdGU6IEZhaWxlZCIsCisJCQkJY2hhbm5lbCwgdGd0KTsKKwkJCWJyZWFrOworCisJCWNhc2UgUERSVl9SQkxEOgorCQkJc3ByaW50ZihzdHIsCisJCQkiQ2hhbm5lbDolMmQgSWQ6JTJkIFN0YXRlOiBSZWJ1aWxkIiwKKwkJCQljaGFubmVsLCB0Z3QpOworCQkJYnJlYWs7CisKKwkJY2FzZSBQRFJWX0hPVFNQQVJFOgorCQkJc3ByaW50ZihzdHIsCisJCQkiQ2hhbm5lbDolMmQgSWQ6JTJkIFN0YXRlOiBIb3Qgc3BhcmUiLAorCQkJCWNoYW5uZWwsIHRndCk7CisJCQlicmVhazsKKworCQlkZWZhdWx0OgorCQkJc3ByaW50ZihzdHIsCisJCQkiQ2hhbm5lbDolMmQgSWQ6JTJkIFN0YXRlOiBVbi1jb25maWd1cmVkIiwKKwkJCQljaGFubmVsLCB0Z3QpOworCQkJYnJlYWs7CisKKwkJfQorCisJCS8qCisJCSAqIFRoaXMgaW50ZXJmYWNlIGRpc3BsYXlzIGlucXVpcmllcyBmb3IgZGlzayBkcml2ZXMKKwkJICogb25seS4gSW5xdXJpZXMgZm9yIGxvZ2ljYWwgZHJpdmVzIGFuZCBub24tZGlzaworCQkgKiBkZXZpY2VzIGFyZSBhdmFpbGFibGUgdGhyb3VnaCAvcHJvYy9zY3NpL3Njc2kKKwkJICovCisJCW1lbXNldChzY3NpX2lucSwgMCwgMjU2KTsKKwkJaWYoIG1lZ2FfaW50ZXJuYWxfZGV2X2lucXVpcnkoYWRhcHRlciwgY2hhbm5lbCwgdGd0LAorCQkJCXNjc2lfaW5xX2RtYV9oYW5kbGUpIHx8CisJCQkJKHNjc2lfaW5xWzBdICYgMHgxRikgIT0gVFlQRV9ESVNLICkgeworCQkJY29udGludWU7CisJCX0KKworCQkvKgorCQkgKiBDaGVjayBmb3Igb3ZlcmZsb3cuIFdlIHByaW50IGxlc3MgdGhhbiAyNDAKKwkJICogY2hhcmFjdGVycyBmb3IgaW5xdWlyeQorCQkgKi8KKwkJaWYoIChsZW4gKyAyNDApID49IFBBR0VfU0laRSApIGJyZWFrOworCisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiJXMuXG4iLCBzdHIpOworCisJCWxlbiArPSBtZWdhX3ByaW50X2lucXVpcnkocGFnZStsZW4sIHNjc2lfaW5xKTsKKwl9CisKK2ZyZWVfcGNpOgorCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgMjU2LCBzY3NpX2lucSwgc2NzaV9pbnFfZG1hX2hhbmRsZSk7CitmcmVlX2lucXVpcnk6CisJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CitmcmVlX3BkZXY6CisJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJcmV0dXJuIGxlbjsKK30KKworCisvKgorICogRGlzcGxheSBzY3NpIGlucXVpcnkKKyAqLworc3RhdGljIGludAorbWVnYV9wcmludF9pbnF1aXJ5KGNoYXIgKnBhZ2UsIGNoYXIgKnNjc2lfaW5xKQoreworCWludAlsZW4gPSAwOworCWludAlpOworCisJbGVuID0gc3ByaW50ZihwYWdlLCAiICBWZW5kb3I6ICIpOworCWZvciggaSA9IDg7IGkgPCAxNjsgaSsrICkgeworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVjIiwgc2NzaV9pbnFbaV0pOworCX0KKworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBNb2RlbDogIik7CisKKwlmb3IoIGkgPSAxNjsgaSA8IDMyOyBpKysgKSB7CisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiJWMiLCBzY3NpX2lucVtpXSk7CisJfQorCisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIFJldjogIik7CisKKwlmb3IoIGkgPSAzMjsgaSA8IDM2OyBpKysgKSB7CisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiJWMiLCBzY3NpX2lucVtpXSk7CisJfQorCisJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJcbiIpOworCisJaSA9IHNjc2lfaW5xWzBdICYgMHgxZjsKKworCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBUeXBlOiAgICVzICIsCisJCWkgPCBNQVhfU0NTSV9ERVZJQ0VfQ09ERSA/IHNjc2lfZGV2aWNlX3R5cGVzW2ldIDoKKwkJICAgIlVua25vd24gICAgICAgICAgIik7CisKKwlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKKwkiICAgICAgICAgICAgICAgICBBTlNJIFNDU0kgcmV2aXNpb246ICUwMngiLCBzY3NpX2lucVsyXSAmIDB4MDcpOworCisJaWYoIChzY3NpX2lucVsyXSAmIDB4MDcpID09IDEgJiYgKHNjc2lfaW5xWzNdICYgMHgwZikgPT0gMSApCisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiIENDU1xuIik7CisJZWxzZQorCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlxuIik7CisKKwlyZXR1cm4gbGVuOworfQorCisKKy8qKgorICogcHJvY19yZHJ2XzEwKCkKKyAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCisgKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCisgKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCisgKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBEaXNwbGF5IHJlYWwgdGltZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9naWNhbCBkcml2ZXMgMCB0aHJvdWdoIDkuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcmRydl8xMChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKKwkJdm9pZCAqZGF0YSkKK3sKKwlhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKKworCSplb2YgPSAxOworCisJcmV0dXJuIChwcm9jX3JkcnYoYWRhcHRlciwgcGFnZSwgMCwgOSkpOworfQorCisKKy8qKgorICogcHJvY19yZHJ2XzIwKCkKKyAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCisgKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCisgKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCisgKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBEaXNwbGF5IHJlYWwgdGltZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9naWNhbCBkcml2ZXMgMCB0aHJvdWdoIDkuCisgKi8KK3N0YXRpYyBpbnQKK3Byb2NfcmRydl8yMChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKKwkJdm9pZCAqZGF0YSkKK3sKKwlhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKKworCSplb2YgPSAxOworCisJcmV0dXJuIChwcm9jX3JkcnYoYWRhcHRlciwgcGFnZSwgMTAsIDE5KSk7Cit9CisKKworLyoqCisgKiBwcm9jX3JkcnZfMzAoKQorICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KKyAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKKyAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKKyAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKKyAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIERpc3BsYXkgcmVhbCB0aW1lIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2dpY2FsIGRyaXZlcyAwIHRocm91Z2ggOS4KKyAqLworc3RhdGljIGludAorcHJvY19yZHJ2XzMwKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAorCQl2b2lkICpkYXRhKQoreworCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOworCisJKmVvZiA9IDE7CisKKwlyZXR1cm4gKHByb2NfcmRydihhZGFwdGVyLCBwYWdlLCAyMCwgMjkpKTsKK30KKworCisvKioKKyAqIHByb2NfcmRydl80MCgpCisgKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgorICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQorICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAorICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCisgKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAorICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRGlzcGxheSByZWFsIHRpbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvZ2ljYWwgZHJpdmVzIDAgdGhyb3VnaCA5LgorICovCitzdGF0aWMgaW50Citwcm9jX3JkcnZfNDAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCisJCXZvaWQgKmRhdGEpCit7CisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CisKKwkqZW9mID0gMTsKKworCXJldHVybiAocHJvY19yZHJ2KGFkYXB0ZXIsIHBhZ2UsIDMwLCAzOSkpOworfQorCisKKy8qKgorICogcHJvY19yZHJ2KCkKKyAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBzdGFydCAtIHN0YXJ0aW5nIGxvZ2ljYWwgZHJpdmUgdG8gZGlzcGxheQorICogQGVuZCAtIGVuZGluZyBsb2dpY2FsIGRyaXZlIHRvIGRpc3BsYXkKKyAqCisgKiBXZSBkbyBub3QgcHJpbnQgdGhlIGlucXVpcnkgaW5mb3JtYXRpb24gc2luY2UgaXRzIGFscmVhZHkgYXZhaWxhYmxlIHRocm91Z2gKKyAqIC9wcm9jL3Njc2kvc2NzaSBpbnRlcmZhY2UKKyAqLworc3RhdGljIGludAorcHJvY19yZHJ2KGFkYXB0ZXJfdCAqYWRhcHRlciwgY2hhciAqcGFnZSwgaW50IHN0YXJ0LCBpbnQgZW5kICkKK3sKKwlkbWFfYWRkcl90CWRtYV9oYW5kbGU7CisJbG9nZHJ2X3BhcmFtCSpscGFyYW07CisJbWVnYWNtZF90CW1jOworCWNoYXIJCSpkaXNrX2FycmF5OworCWRtYV9hZGRyX3QJZGlza19hcnJheV9kbWFfaGFuZGxlOworCWNhZGRyX3QJCWlucXVpcnk7CisJc3RydWN0IHBjaV9kZXYJKnBkZXY7CisJdTgJKnJkcnZfc3RhdGU7CisJaW50CW51bV9sZHJ2OworCXUzMglhcnJheV9zejsKKwlpbnQJbGVuID0gMDsKKwlpbnQJaTsKKworCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSB7CisJCXJldHVybiBsZW47CisJfQorCisJaWYoIChpbnF1aXJ5ID0gbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KCZkbWFfaGFuZGxlLCBwZGV2KSkgPT0gTlVMTCApIHsKKwkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCQlyZXR1cm4gbGVuOworCX0KKworCWlmKCBtZWdhX2FkYXBpbnEoYWRhcHRlciwgZG1hX2hhbmRsZSkgIT0gMCApIHsKKworCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJBZGFwdGVyIGlucXVpcnkgZmFpbGVkLlxuIik7CisKKwkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IGlucXVpcnkgZmFpbGVkLlxuIik7CisKKwkJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CisKKwkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJCXJldHVybiBsZW47CisJfQorCisJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOworCisJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEICkgeworCQlhcnJheV9zeiA9IHNpemVvZihkaXNrX2FycmF5XzQwbGQpOworCisJCXJkcnZfc3RhdGUgPSAoKG1lZ2FfaW5xdWlyeTMgKilpbnF1aXJ5KS0+bGRydl9zdGF0ZTsKKworCQludW1fbGRydiA9ICgobWVnYV9pbnF1aXJ5MyAqKWlucXVpcnkpLT5udW1fbGRydjsKKwl9CisJZWxzZSB7CisJCWFycmF5X3N6ID0gc2l6ZW9mKGRpc2tfYXJyYXlfOGxkKTsKKworCQlyZHJ2X3N0YXRlID0gKChtcmFpZF9leHRfaW5xdWlyeSAqKWlucXVpcnkpLT4KKwkJCXJhaWRfaW5xLmxvZ2Rydl9pbmZvLmxkcnZfc3RhdGU7CisKKwkJbnVtX2xkcnYgPSAoKG1yYWlkX2V4dF9pbnF1aXJ5ICopaW5xdWlyeSktPgorCQkJcmFpZF9pbnEubG9nZHJ2X2luZm8ubnVtX2xkcnY7CisJfQorCisJZGlza19hcnJheSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsIGFycmF5X3N6LAorCQkJJmRpc2tfYXJyYXlfZG1hX2hhbmRsZSk7CisKKwlpZiggZGlza19hcnJheSA9PSBOVUxMICkgeworCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJtZW1vcnkgbm90IGF2YWlsYWJsZS5cbiIpOworCisJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOworCisJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKKworCQlyZXR1cm4gbGVuOworCX0KKworCW1jLnhmZXJhZGRyID0gKHUzMilkaXNrX2FycmF5X2RtYV9oYW5kbGU7CisKKwlpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CisJCW1jLmNtZCA9IEZDX05FV19DT05GSUc7CisJCW1jLm9wY29kZSA9IE9QX0RDTURfUkVBRF9DT05GSUc7CisKKwkJaWYoIG1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLCBOVUxMKSApIHsKKworCQkJbGVuID0gc3ByaW50ZihwYWdlLCAiNDBMRCByZWFkIGNvbmZpZyBmYWlsZWQuXG4iKTsKKworCQkJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CisKKwkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgYXJyYXlfc3osIGRpc2tfYXJyYXksCisJCQkJCWRpc2tfYXJyYXlfZG1hX2hhbmRsZSk7CisKKwkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKKworCQkJcmV0dXJuIGxlbjsKKwkJfQorCisJfQorCWVsc2UgeworCQltYy5jbWQgPSBORVdfUkVBRF9DT05GSUdfOExEOworCisJCWlmKCBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCkgKSB7CisKKwkJCW1jLmNtZCA9IFJFQURfQ09ORklHXzhMRDsKKworCQkJaWYoIG1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLAorCQkJCQkJTlVMTCkgKXsKKworCQkJCWxlbiA9IHNwcmludGYocGFnZSwKKwkJCQkJIjhMRCByZWFkIGNvbmZpZyBmYWlsZWQuXG4iKTsKKworCQkJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOworCisJCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCBhcnJheV9zeiwKKwkJCQkJCWRpc2tfYXJyYXksCisJCQkJCQlkaXNrX2FycmF5X2RtYV9oYW5kbGUpOworCisJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJCQkJcmV0dXJuIGxlbjsKKwkJCX0KKwkJfQorCX0KKworCWZvciggaSA9IHN0YXJ0OyBpIDwgKCAoZW5kKzEgPCBudW1fbGRydikgPyBlbmQrMSA6IG51bV9sZHJ2ICk7IGkrKyApIHsKKworCQlpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CisJCQlscGFyYW0gPQorCQkJJigoZGlza19hcnJheV80MGxkICopZGlza19hcnJheSktPmxkcnZbaV0ubHBhcmFtOworCQl9CisJCWVsc2UgeworCQkJbHBhcmFtID0KKwkJCSYoKGRpc2tfYXJyYXlfOGxkICopZGlza19hcnJheSktPmxkcnZbaV0ubHBhcmFtOworCQl9CisKKwkJLyoKKwkJICogQ2hlY2sgZm9yIG92ZXJmbG93LiBXZSBwcmludCBsZXNzIHRoYW4gMjQwIGNoYXJhY3RlcnMgZm9yCisJCSAqIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggbG9naWNhbCBkcml2ZS4KKwkJICovCisJCWlmKCAobGVuICsgMjQwKSA+PSBQQUdFX1NJWkUgKSBicmVhazsKKworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkxvZ2ljYWwgZHJpdmU6JTJkOiwgIiwgaSk7CisKKwkJc3dpdGNoKCByZHJ2X3N0YXRlW2ldICYgMHgwRiApIHsKKwkJY2FzZSBSRFJWX09GRkxJTkU6CisJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN0YXRlOiBvZmZsaW5lIik7CisJCQlicmVhazsKKworCQljYXNlIFJEUlZfREVHUkFERUQ6CisJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN0YXRlOiBkZWdyYWRlZCIpOworCQkJYnJlYWs7CisKKwkJY2FzZSBSRFJWX09QVElNQUw6CisJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN0YXRlOiBvcHRpbWFsIik7CisJCQlicmVhazsKKworCQljYXNlIFJEUlZfREVMRVRFRDoKKwkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAic3RhdGU6IGRlbGV0ZWQiKTsKKwkJCWJyZWFrOworCisJCWRlZmF1bHQ6CisJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN0YXRlOiB1bmtub3duIik7CisJCQlicmVhazsKKwkJfQorCisJCS8qCisJCSAqIENoZWNrIGlmIGNoZWNrIGNvbnNpc3RlbmN5IG9yIGluaXRpYWxpemF0aW9uIGlzIGdvaW5nIG9uCisJCSAqIGZvciB0aGlzIGxvZ2ljYWwgZHJpdmUuCisJCSAqLworCQlpZiggKHJkcnZfc3RhdGVbaV0gJiAweEYwKSA9PSAweDIwICkgeworCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCisJCQkJCSIsIGNoZWNrLWNvbnNpc3RlbmN5IGluIHByb2dyZXNzIik7CisJCX0KKwkJZWxzZSBpZiggKHJkcnZfc3RhdGVbaV0gJiAweEYwKSA9PSAweDEwICkgeworCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCisJCQkJCSIsIGluaXRpYWxpemF0aW9uIGluIHByb2dyZXNzIik7CisJCX0KKwkJCisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiXG4iKTsKKworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlNwYW4gZGVwdGg6JTNkLCAiLAorCQkJCWxwYXJhbS0+c3Bhbl9kZXB0aCk7CisKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJSQUlEIGxldmVsOiUzZCwgIiwKKwkJCQlscGFyYW0tPmxldmVsKTsKKworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlN0cmlwZSBzaXplOiUzZCwgIiwKKwkJCQlscGFyYW0tPnN0cmlwZV9zeiA/IGxwYXJhbS0+c3RyaXBlX3N6LzI6IDEyOCk7CisKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJSb3cgc2l6ZTolM2RcbiIsCisJCQkJbHBhcmFtLT5yb3dfc2l6ZSk7CisKKworCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlJlYWQgUG9saWN5OiAiKTsKKworCQlzd2l0Y2gobHBhcmFtLT5yZWFkX2FoZWFkKSB7CisKKwkJY2FzZSBOT19SRUFEX0FIRUFEOgorCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJObyByZWFkIGFoZWFkLCAiKTsKKwkJCWJyZWFrOworCisJCWNhc2UgUkVBRF9BSEVBRDoKKwkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiUmVhZCBhaGVhZCwgIik7CisJCQlicmVhazsKKworCQljYXNlIEFEQVBfUkVBRF9BSEVBRDoKKwkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiQWRhcHRpdmUsICIpOworCQkJYnJlYWs7CisKKwkJfQorCisJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiV3JpdGUgUG9saWN5OiAiKTsKKworCQlzd2l0Y2gobHBhcmFtLT53cml0ZV9tb2RlKSB7CisKKwkJY2FzZSBXUk1PREVfV1JJVEVfVEhSVToKKwkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiV3JpdGUgdGhydSwgIik7CisJCQlicmVhazsKKworCQljYXNlIFdSTU9ERV9XUklURV9CQUNLOgorCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJXcml0ZSBiYWNrLCAiKTsKKwkJCWJyZWFrOworCQl9CisKKwkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJDYWNoZSBQb2xpY3k6ICIpOworCisJCXN3aXRjaChscGFyYW0tPmRpcmVjdF9pbykgeworCisJCWNhc2UgQ0FDSEVEX0lPOgorCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJDYWNoZWQgSU9cblxuIik7CisJCQlicmVhazsKKworCQljYXNlIERJUkVDVF9JTzoKKwkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiRGlyZWN0IElPXG5cbiIpOworCQkJYnJlYWs7CisJCX0KKwl9CisKKwltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKKworCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgYXJyYXlfc3osIGRpc2tfYXJyYXksCisJCQlkaXNrX2FycmF5X2RtYV9oYW5kbGUpOworCisJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJcmV0dXJuIGxlbjsKK30KKworI2VuZGlmCisKKworLyoqCisgKiBtZWdhcmFpZF9iaW9zcGFyYW0oKQorICoKKyAqIFJldHVybiB0aGUgZGlzayBnZW9tZXRyeSBmb3IgYSBwYXJ0aWN1bGFyIGRpc2sKKyAqLworc3RhdGljIGludAorbWVnYXJhaWRfYmlvc3BhcmFtKHN0cnVjdCBzY3NpX2RldmljZSAqc2Rldiwgc3RydWN0IGJsb2NrX2RldmljZSAqYmRldiwKKwkJICAgIHNlY3Rvcl90IGNhcGFjaXR5LCBpbnQgZ2VvbVtdKQoreworCWFkYXB0ZXJfdAkqYWRhcHRlcjsKKwl1bnNpZ25lZCBjaGFyCSpiaDsKKwlpbnQJaGVhZHM7CisJaW50CXNlY3RvcnM7CisJaW50CWN5bGluZGVyczsKKwlpbnQJcnZhbDsKKworCS8qIEdldCBwb2ludGVyIHRvIGhvc3QgY29uZmlnIHN0cnVjdHVyZSAqLworCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopc2Rldi0+aG9zdC0+aG9zdGRhdGE7CisKKwlpZiAoSVNfUkFJRF9DSChhZGFwdGVyLCBzZGV2LT5jaGFubmVsKSkgeworCQkJLyogRGVmYXVsdCBoZWFkcyAoNjQpICYgc2VjdG9ycyAoMzIpICovCisJCQloZWFkcyA9IDY0OworCQkJc2VjdG9ycyA9IDMyOworCQkJY3lsaW5kZXJzID0gKHVsb25nKWNhcGFjaXR5IC8gKGhlYWRzICogc2VjdG9ycyk7CisKKwkJCS8qCisJCQkgKiBIYW5kbGUgZXh0ZW5kZWQgdHJhbnNsYXRpb24gc2l6ZSBmb3IgbG9naWNhbCBkcml2ZXMKKwkJCSAqID4gMUdiCisJCQkgKi8KKwkJCWlmICgodWxvbmcpY2FwYWNpdHkgPj0gMHgyMDAwMDApIHsKKwkJCQloZWFkcyA9IDI1NTsKKwkJCQlzZWN0b3JzID0gNjM7CisJCQkJY3lsaW5kZXJzID0gKHVsb25nKWNhcGFjaXR5IC8gKGhlYWRzICogc2VjdG9ycyk7CisJCQl9CisKKwkJCS8qIHJldHVybiByZXN1bHQgKi8KKwkJCWdlb21bMF0gPSBoZWFkczsKKwkJCWdlb21bMV0gPSBzZWN0b3JzOworCQkJZ2VvbVsyXSA9IGN5bGluZGVyczsKKwl9CisJZWxzZSB7CisJCWJoID0gc2NzaV9iaW9zX3B0YWJsZShiZGV2KTsKKworCQlpZiggYmggKSB7CisJCQlydmFsID0gc2NzaV9wYXJ0c2l6ZShiaCwgY2FwYWNpdHksCisJCQkJCSAgICAmZ2VvbVsyXSwgJmdlb21bMF0sICZnZW9tWzFdKTsKKwkJCWtmcmVlKGJoKTsKKwkJCWlmKCBydmFsICE9IC0xICkKKwkJCQlyZXR1cm4gcnZhbDsKKwkJfQorCisJCXByaW50ayhLRVJOX0lORk8KKwkJIm1lZ2FyYWlkOiBpbnZhbGlkIHBhcnRpdGlvbiBvbiB0aGlzIGRpc2sgb24gY2hhbm5lbCAlZFxuIiwKKwkJCQlzZGV2LT5jaGFubmVsKTsKKworCQkvKiBEZWZhdWx0IGhlYWRzICg2NCkgJiBzZWN0b3JzICgzMikgKi8KKwkJaGVhZHMgPSA2NDsKKwkJc2VjdG9ycyA9IDMyOworCQljeWxpbmRlcnMgPSAodWxvbmcpY2FwYWNpdHkgLyAoaGVhZHMgKiBzZWN0b3JzKTsKKworCQkvKiBIYW5kbGUgZXh0ZW5kZWQgdHJhbnNsYXRpb24gc2l6ZSBmb3IgbG9naWNhbCBkcml2ZXMgPiAxR2IgKi8KKwkJaWYgKCh1bG9uZyljYXBhY2l0eSA+PSAweDIwMDAwMCkgeworCQkJaGVhZHMgPSAyNTU7CisJCQlzZWN0b3JzID0gNjM7CisJCQljeWxpbmRlcnMgPSAodWxvbmcpY2FwYWNpdHkgLyAoaGVhZHMgKiBzZWN0b3JzKTsKKwkJfQorCisJCS8qIHJldHVybiByZXN1bHQgKi8KKwkJZ2VvbVswXSA9IGhlYWRzOworCQlnZW9tWzFdID0gc2VjdG9yczsKKwkJZ2VvbVsyXSA9IGN5bGluZGVyczsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworLyoqCisgKiBtZWdhX2luaXRfc2NiKCkKKyAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQorICoKKyAqIEFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIHZhcmlvdXMgcG9pbnRlcnMgaW4gdGhlIHNjYiBzdHJ1Y3R1cmVzOgorICogc2NhdHRlci1nYXRoZXIgbGlzdCBwb2ludGVyLCBwYXNzdGhydSBhbmQgZXh0ZW5kZWQgcGFzc3RocnUgc3RydWN0dXJlCisgKiBwb2ludGVycy4KKyAqLworc3RhdGljIGludAorbWVnYV9pbml0X3NjYihhZGFwdGVyX3QgKmFkYXB0ZXIpCit7CisJc2NiX3QJKnNjYjsKKwlpbnQJaTsKKworCWZvciggaSA9IDA7IGkgPCBhZGFwdGVyLT5tYXhfY21kczsgaSsrICkgeworCisJCXNjYiA9ICZhZGFwdGVyLT5zY2JfbGlzdFtpXTsKKworCQlzY2ItPnNnbDY0ID0gTlVMTDsKKwkJc2NiLT5zZ2wgPSBOVUxMOworCQlzY2ItPnB0aHJ1ID0gTlVMTDsKKwkJc2NiLT5lcHRocnUgPSBOVUxMOworCX0KKworCWZvciggaSA9IDA7IGkgPCBhZGFwdGVyLT5tYXhfY21kczsgaSsrICkgeworCisJCXNjYiA9ICZhZGFwdGVyLT5zY2JfbGlzdFtpXTsKKworCQlzY2ItPmlkeCA9IGk7CisKKwkJc2NiLT5zZ2w2NCA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKKwkJCQlzaXplb2YobWVnYV9zZ2w2NCkgKiBhZGFwdGVyLT5zZ2xlbiwKKwkJCQkmc2NiLT5zZ2xfZG1hX2FkZHIpOworCisJCXNjYi0+c2dsID0gKG1lZ2Ffc2dsaXN0ICopc2NiLT5zZ2w2NDsKKworCQlpZiggIXNjYi0+c2dsICkgeworCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiUkFJRDogQ2FuJ3QgYWxsb2NhdGUgc2dsaXN0LlxuIik7CisJCQltZWdhX2ZyZWVfc2dsKGFkYXB0ZXIpOworCQkJcmV0dXJuIC0xOworCQl9CisKKwkJc2NiLT5wdGhydSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKKwkJCQlzaXplb2YobWVnYV9wYXNzdGhydSksCisJCQkJJnNjYi0+cHRocnVfZG1hX2FkZHIpOworCisJCWlmKCAhc2NiLT5wdGhydSApIHsKKwkJCXByaW50ayhLRVJOX1dBUk5JTkcgIlJBSUQ6IENhbid0IGFsbG9jYXRlIHBhc3N0aHJ1LlxuIik7CisJCQltZWdhX2ZyZWVfc2dsKGFkYXB0ZXIpOworCQkJcmV0dXJuIC0xOworCQl9CisKKwkJc2NiLT5lcHRocnUgPSBwY2lfYWxsb2NfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsCisJCQkJc2l6ZW9mKG1lZ2FfZXh0X3Bhc3N0aHJ1KSwKKwkJCQkmc2NiLT5lcHRocnVfZG1hX2FkZHIpOworCisJCWlmKCAhc2NiLT5lcHRocnUgKSB7CisJCQlwcmludGsoS0VSTl9XQVJOSU5HCisJCQkJIkNhbid0IGFsbG9jYXRlIGV4dGVuZGVkIHBhc3N0aHJ1LlxuIik7CisJCQltZWdhX2ZyZWVfc2dsKGFkYXB0ZXIpOworCQkJcmV0dXJuIC0xOworCQl9CisKKworCQlzY2ItPmRtYV90eXBlID0gTUVHQV9ETUFfVFlQRV9OT05FOworCisJCS8qCisJCSAqIExpbmsgdG8gZnJlZSBsaXN0CisJCSAqIGxvY2sgbm90IHJlcXVpcmVkIHNpbmNlIHdlIGFyZSBsb2FkaW5nIHRoZSBkcml2ZXIsIHNvIG5vCisJCSAqIGNvbW1hbmRzIHBvc3NpYmxlIHJpZ2h0IG5vdy4KKwkJICovCisJCXNjYi0+c3RhdGUgPSBTQ0JfRlJFRTsKKwkJc2NiLT5jbWQgPSBOVUxMOworCQlsaXN0X2FkZCgmc2NiLT5saXN0LCAmYWRhcHRlci0+ZnJlZV9saXN0KTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworCisvKioKKyAqIG1lZ2FkZXZfb3BlbigpCisgKiBAaW5vZGUgLSB1bnVzZWQKKyAqIEBmaWxlcCAtIHVudXNlZAorICoKKyAqIFJvdXRpbmVzIGZvciB0aGUgY2hhcmFjdGVyL2lvY3RsIGludGVyZmFjZSB0byB0aGUgZHJpdmVyLiBGaW5kIG91dCBpZiB0aGlzCisgKiBpcyBhIHZhbGlkIG9wZW4uIElmIHllcywgaW5jcmVtZW50IHRoZSBtb2R1bGUgdXNlIGNvdW50IHNvIHRoYXQgaXQgY2Fubm90CisgKiBiZSB1bmxvYWRlZC4KKyAqLworc3RhdGljIGludAorbWVnYWRldl9vcGVuIChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZXApCit7CisJLyoKKwkgKiBPbmx5IGFsbG93IHN1cGVydXNlciB0byBhY2Nlc3MgcHJpdmF0ZSBpb2N0bCBpbnRlcmZhY2UKKwkgKi8KKwlpZiggIWNhcGFibGUoQ0FQX1NZU19BRE1JTikgKSByZXR1cm4gLUVBQ0NFUzsKKworCXJldHVybiAwOworfQorCisKKy8qKgorICogbWVnYWRldl9pb2N0bCgpCisgKiBAaW5vZGUgLSBPdXIgZGV2aWNlIGlub2RlCisgKiBAZmlsZXAgLSB1bnVzZWQKKyAqIEBjbWQgLSBpb2N0bCBjb21tYW5kCisgKiBAYXJnIC0gdXNlciBidWZmZXIKKyAqCisgKiBpb2N0bCBlbnRyeSBwb2ludCBmb3Igb3VyIHByaXZhdGUgaW9jdGwgaW50ZXJmYWNlLiBXZSBtb3ZlIHRoZSBkYXRhIGluIGZyb20KKyAqIHRoZSB1c2VyIHNwYWNlLCBwcmVwYXJlIHRoZSBjb21tYW5kIChpZiBuZWNlc3NhcnksIGNvbnZlcnQgdGhlIG9sZCBNSU1ECisgKiBpb2N0bCB0byBuZXcgaW9jdGwgY29tbWFuZCksIGFuZCBpc3N1ZSBhIHN5bmNocm9ub3VzIGNvbW1hbmQgdG8gdGhlCisgKiBjb250cm9sbGVyLgorICovCitzdGF0aWMgaW50CittZWdhZGV2X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlcCwgdW5zaWduZWQgaW50IGNtZCwKKwkJdW5zaWduZWQgbG9uZyBhcmcpCit7CisJYWRhcHRlcl90CSphZGFwdGVyOworCW5pdGlvY3RsX3QJdWlvYzsKKwlpbnQJCWFkYXBubzsKKwlpbnQJCXJ2YWw7CisJbWVnYV9wYXNzdGhydQlfX3VzZXIgKnVwdGhydTsJLyogdXNlciBhZGRyZXNzIGZvciBwYXNzdGhydSAqLworCW1lZ2FfcGFzc3RocnUJKnB0aHJ1OwkJLyogY29weSB1c2VyIHBhc3N0aHJ1IGhlcmUgKi8KKwlkbWFfYWRkcl90CXB0aHJ1X2RtYV9obmRsOworCXZvaWQJCSpkYXRhID0gTlVMTDsJLyogZGF0YSB0byBiZSB0cmFuc2ZlcnJlZCAqLworCWRtYV9hZGRyX3QJZGF0YV9kbWFfaG5kbDsJLyogZG1hIGhhbmRsZSBmb3IgZGF0YSB4ZmVyIGFyZWEgKi8KKwltZWdhY21kX3QJbWM7CisJbWVnYXN0YXRfdAlfX3VzZXIgKnVzdGF0czsKKwlpbnQJCW51bV9sZHJ2OworCXUzMgkJdXhmZXJhZGRyID0gMDsKKwlzdHJ1Y3QgcGNpX2RldgkqcGRldjsKKworCXVzdGF0cyA9IE5VTEw7IC8qIGF2b2lkIGNvbXBpbGF0aW9uIHdhcm5pbmdzICovCisJbnVtX2xkcnYgPSAwOworCisJLyoKKwkgKiBNYWtlIHN1cmUgb25seSBVU0NTSUNNRCBhcmUgaXNzdWVkIHRocm91Z2ggdGhpcyBpbnRlcmZhY2UuCisJICogTUlNRCBhcHBsaWNhdGlvbiB3b3VsZCBzdGlsbCBmaXJlIGRpZmZlcmVudCBjb21tYW5kLgorCSAqLworCWlmKCAoX0lPQ19UWVBFKGNtZCkgIT0gTUVHQUlPQ19NQUdJQykgJiYgKGNtZCAhPSBVU0NTSUNNRCkgKSB7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCS8qCisJICogQ2hlY2sgYW5kIGNvbnZlcnQgYSBwb3NzaWJsZSBNSU1EIGNvbW1hbmQgdG8gTklUIGNvbW1hbmQuCisJICogbWVnYV9tX3RvX24oKSBjb3BpZXMgdGhlIGRhdGEgZnJvbSB0aGUgdXNlciBzcGFjZSwgc28gd2UgZG8gbm90CisJICogaGF2ZSB0byBkbyBpdCBoZXJlLgorCSAqIE5PVEU6IFdlIHdpbGwgbmVlZCBzb21lIHVzZXIgYWRkcmVzcyB0byBjb3B5b3V0IHRoZSBkYXRhLCB0aGVyZWZvcmUKKwkgKiB0aGUgaW50ZWZhY2UgbGF5ZXIgd2lsbCBhbHNvIHByb3ZpZGUgdXMgd2l0aCB0aGUgcmVxdWlyZWQgdXNlcgorCSAqIGFkZHJlc3Nlcy4KKwkgKi8KKwltZW1zZXQoJnVpb2MsIDAsIHNpemVvZihuaXRpb2N0bF90KSk7CisJaWYoIChydmFsID0gbWVnYV9tX3RvX24oICh2b2lkIF9fdXNlciAqKWFyZywgJnVpb2MpKSAhPSAwICkKKwkJcmV0dXJuIHJ2YWw7CisKKworCXN3aXRjaCggdWlvYy5vcGNvZGUgKSB7CisKKwljYXNlIEdFVF9EUklWRVJfVkVSOgorCQlpZiggcHV0X3VzZXIoZHJpdmVyX3ZlciwgKHUzMiBfX3VzZXIgKil1aW9jLnVpb2NfdWFkZHIpICkKKwkJCXJldHVybiAoLUVGQVVMVCk7CisKKwkJYnJlYWs7CisKKwljYXNlIEdFVF9OX0FEQVA6CisJCWlmKCBwdXRfdXNlcihoYmFfY291bnQsICh1MzIgX191c2VyICopdWlvYy51aW9jX3VhZGRyKSApCisJCQlyZXR1cm4gKC1FRkFVTFQpOworCisJCS8qCisJCSAqIFNodWNrcy4gTUlNRCBpbnRlcmZhY2UgcmV0dXJucyBhIHBvc2l0aXZlIHZhbHVlIGZvciBudW1iZXIKKwkJICogb2YgYWRhcHRlcnMuIFRPRE86IENoYW5nZSBpdCB0byByZXR1cm4gMCB3aGVuIHRoZXJlIGlzIG5vCisJCSAqIGFwcGxpY2F0aW8gdXNpbmcgbWltZCBpbnRlcmZhY2UuCisJCSAqLworCQlyZXR1cm4gaGJhX2NvdW50OworCisJY2FzZSBHRVRfQURBUF9JTkZPOgorCisJCS8qCisJCSAqIFdoaWNoIGFkYXB0ZXIKKwkJICovCisJCWlmKCAoYWRhcG5vID0gR0VUQURBUCh1aW9jLmFkYXBubykpID49IGhiYV9jb3VudCApCisJCQlyZXR1cm4gKC1FTk9ERVYpOworCisJCWlmKCBjb3B5X3RvX3VzZXIodWlvYy51aW9jX3VhZGRyLCBtY29udHJvbGxlcithZGFwbm8sCisJCQkJc2l6ZW9mKHN0cnVjdCBtY29udHJvbGxlcikpICkKKwkJCXJldHVybiAoLUVGQVVMVCk7CisJCWJyZWFrOworCisjaWYgTUVHQV9IQVZFX1NUQVRTCisKKwljYXNlIEdFVF9TVEFUUzoKKwkJLyoKKwkJICogV2hpY2ggYWRhcHRlcgorCQkgKi8KKwkJaWYoIChhZGFwbm8gPSBHRVRBREFQKHVpb2MuYWRhcG5vKSkgPj0gaGJhX2NvdW50ICkKKwkJCXJldHVybiAoLUVOT0RFVik7CisKKwkJYWRhcHRlciA9IGhiYV9zb2Z0X3N0YXRlW2FkYXBub107CisKKwkJdXN0YXRzID0gdWlvYy51aW9jX3VhZGRyOworCisJCWlmKCBjb3B5X2Zyb21fdXNlcigmbnVtX2xkcnYsICZ1c3RhdHMtPm51bV9sZHJ2LCBzaXplb2YoaW50KSkgKQorCQkJcmV0dXJuICgtRUZBVUxUKTsKKworCQkvKgorCQkgKiBDaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIHRoZSBsb2dpY2FsIGRyaXZlIG51bWJlcgorCQkgKi8KKwkJaWYoIG51bV9sZHJ2ID49IE1BWF9MT0dJQ0FMX0RSSVZFU180MExEICkgcmV0dXJuIC1FSU5WQUw7CisKKwkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPm5yZWFkcywgYWRhcHRlci0+bnJlYWRzLAorCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQorCQkJcmV0dXJuIC1FRkFVTFQ7CisKKwkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPm5yZWFkYmxvY2tzLCBhZGFwdGVyLT5ucmVhZGJsb2NrcywKKwkJCQkJbnVtX2xkcnYqc2l6ZW9mKHUzMikpICkKKwkJCXJldHVybiAtRUZBVUxUOworCisJCWlmKCBjb3B5X3RvX3VzZXIodXN0YXRzLT5ud3JpdGVzLCBhZGFwdGVyLT5ud3JpdGVzLAorCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQorCQkJcmV0dXJuIC1FRkFVTFQ7CisKKwkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPm53cml0ZWJsb2NrcywgYWRhcHRlci0+bndyaXRlYmxvY2tzLAorCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQorCQkJcmV0dXJuIC1FRkFVTFQ7CisKKwkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPnJkX2Vycm9ycywgYWRhcHRlci0+cmRfZXJyb3JzLAorCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQorCQkJcmV0dXJuIC1FRkFVTFQ7CisKKwkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPndyX2Vycm9ycywgYWRhcHRlci0+d3JfZXJyb3JzLAorCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQorCQkJcmV0dXJuIC1FRkFVTFQ7CisKKwkJcmV0dXJuIDA7CisKKyNlbmRpZgorCWNhc2UgTUJPWF9DTUQ6CisKKwkJLyoKKwkJICogV2hpY2ggYWRhcHRlcgorCQkgKi8KKwkJaWYoIChhZGFwbm8gPSBHRVRBREFQKHVpb2MuYWRhcG5vKSkgPj0gaGJhX2NvdW50ICkKKwkJCXJldHVybiAoLUVOT0RFVik7CisKKwkJYWRhcHRlciA9IGhiYV9zb2Z0X3N0YXRlW2FkYXBub107CisKKwkJLyoKKwkJICogRGVsZXRpb24gb2YgbG9naWNhbCBkcml2ZSBpcyBhIHNwZWNpYWwgY2FzZS4gVGhlIGFkYXB0ZXIKKwkJICogc2hvdWxkIGJlIHF1aWVzY2VudCBiZWZvcmUgdGhpcyBjb21tYW5kIGlzIGlzc3VlZC4KKwkJICovCisJCWlmKCB1aW9jLnVpb2Nfcm1ib3hbMF0gPT0gRkNfREVMX0xPR0RSViAmJgorCQkJCXVpb2MudWlvY19ybWJveFsyXSA9PSBPUF9ERUxfTE9HRFJWICkgeworCisJCQkvKgorCQkJICogRG8gd2Ugc3VwcG9ydCB0aGlzIGZlYXR1cmUKKwkJCSAqLworCQkJaWYoICFhZGFwdGVyLT5zdXBwb3J0X3JhbmRvbV9kZWwgKSB7CisJCQkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IGxvZ2RydiAiKTsKKwkJCQlwcmludGsoImRlbGV0ZSBvbiBub24tc3VwcG9ydGluZyBGL1cuXG4iKTsKKworCQkJCXJldHVybiAoLUVJTlZBTCk7CisJCQl9CisKKwkJCXJ2YWwgPSBtZWdhX2RlbF9sb2dkcnYoIGFkYXB0ZXIsIHVpb2MudWlvY19ybWJveFszXSApOworCisJCQlpZiggcnZhbCA9PSAwICkgeworCQkJCW1lbXNldCgmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKKworCQkJCW1jLnN0YXR1cyA9IHJ2YWw7CisKKwkJCQlydmFsID0gbWVnYV9uX3RvX20oKHZvaWQgX191c2VyICopYXJnLCAmbWMpOworCQkJfQorCisJCQlyZXR1cm4gcnZhbDsKKwkJfQorCQkvKgorCQkgKiBUaGlzIGludGVyZmFjZSBvbmx5IHN1cHBvcnQgdGhlIHJlZ3VsYXIgcGFzc3RocnUgY29tbWFuZHMuCisJCSAqIFJlamVjdCBleHRlbmRlZCBwYXNzdGhydSBhbmQgNjQtYml0IHBhc3N0aHJ1CisJCSAqLworCQlpZiggdWlvYy51aW9jX3JtYm94WzBdID09IE1FR0FfTUJPWENNRF9QQVNTVEhSVTY0IHx8CisJCQl1aW9jLnVpb2Nfcm1ib3hbMF0gPT0gTUVHQV9NQk9YQ01EX0VYVFBUSFJVICkgeworCisJCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogcmVqZWN0ZWQgcGFzc3RocnUuXG4iKTsKKworCQkJcmV0dXJuICgtRUlOVkFMKTsKKwkJfQorCisJCS8qCisJCSAqIEZvciBhbGwgaW50ZXJuYWwgY29tbWFuZHMsIHRoZSBidWZmZXIgbXVzdCBiZSBhbGxvY2F0ZWQgaW4KKwkJICogPDRHQiBhZGRyZXNzIHJhbmdlCisJCSAqLworCQlpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkKKwkJCXJldHVybiAtRUlPOworCisJCS8qIElzIGl0IGEgcGFzc3RocnUgY29tbWFuZCBvciBhIERDTUQgKi8KKwkJaWYoIHVpb2MudWlvY19ybWJveFswXSA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlUgKSB7CisJCQkvKiBQYXNzdGhydSBjb21tYW5kcyAqLworCisJCQlwdGhydSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsCisJCQkJCXNpemVvZihtZWdhX3Bhc3N0aHJ1KSwKKwkJCQkJJnB0aHJ1X2RtYV9obmRsKTsKKworCQkJaWYoIHB0aHJ1ID09IE5VTEwgKSB7CisJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCQkJCXJldHVybiAoLUVOT01FTSk7CisJCQl9CisKKwkJCS8qCisJCQkgKiBUaGUgdXNlciBwYXNzdGhydSBzdHJ1Y3R1cmUKKwkJCSAqLworCQkJdXB0aHJ1ID0gKG1lZ2FfcGFzc3RocnUgX191c2VyICopTUJPWCh1aW9jKS0+eGZlcmFkZHI7CisKKwkJCS8qCisJCQkgKiBDb3B5IGluIHRoZSB1c2VyIHBhc3N0aHJ1IGhlcmUuCisJCQkgKi8KKwkJCWlmKCBjb3B5X2Zyb21fdXNlcihwdGhydSwgdXB0aHJ1LAorCQkJCQkJc2l6ZW9mKG1lZ2FfcGFzc3RocnUpKSApIHsKKworCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKKwkJCQkJCXNpemVvZihtZWdhX3Bhc3N0aHJ1KSwgcHRocnUsCisJCQkJCQlwdGhydV9kbWFfaG5kbCk7CisKKwkJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CisKKwkJCQlyZXR1cm4gKC1FRkFVTFQpOworCQkJfQorCisJCQkvKgorCQkJICogSXMgdGhlcmUgYSBkYXRhIHRyYW5zZmVyCisJCQkgKi8KKwkJCWlmKCBwdGhydS0+ZGF0YXhmZXJsZW4gKSB7CisJCQkJZGF0YSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsCisJCQkJCQlwdGhydS0+ZGF0YXhmZXJsZW4sCisJCQkJCQkmZGF0YV9kbWFfaG5kbCk7CisKKwkJCQlpZiggZGF0YSA9PSBOVUxMICkgeworCQkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCisJCQkJCQkJc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLAorCQkJCQkJCXB0aHJ1LAorCQkJCQkJCXB0aHJ1X2RtYV9obmRsKTsKKworCQkJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CisKKwkJCQkJcmV0dXJuICgtRU5PTUVNKTsKKwkJCQl9CisKKwkJCQkvKgorCQkJCSAqIFNhdmUgdGhlIHVzZXIgYWRkcmVzcyBhbmQgcG9pbnQgdGhlIGtlcm5lbAorCQkJCSAqIGFkZHJlc3MgYXQganVzdCBhbGxvY2F0ZWQgbWVtb3J5CisJCQkJICovCisJCQkJdXhmZXJhZGRyID0gcHRocnUtPmRhdGF4ZmVyYWRkcjsKKwkJCQlwdGhydS0+ZGF0YXhmZXJhZGRyID0gZGF0YV9kbWFfaG5kbDsKKwkJCX0KKworCisJCQkvKgorCQkJICogSXMgZGF0YSBjb21pbmcgZG93bi1zdHJlYW0KKwkJCSAqLworCQkJaWYoIHB0aHJ1LT5kYXRheGZlcmxlbiAmJiAodWlvYy5mbGFncyAmIFVJT0NfV1IpICkgeworCQkJCS8qCisJCQkJICogR2V0IHRoZSB1c2VyIGRhdGEKKwkJCQkgKi8KKwkJCQlpZiggY29weV9mcm9tX3VzZXIoZGF0YSwgKGNoYXIgX191c2VyICopdXhmZXJhZGRyLAorCQkJCQkJCXB0aHJ1LT5kYXRheGZlcmxlbikgKSB7CisJCQkJCXJ2YWwgPSAoLUVGQVVMVCk7CisJCQkJCWdvdG8gZnJlZW1lbV9hbmRfcmV0dXJuOworCQkJCX0KKwkJCX0KKworCQkJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOworCisJCQltYy5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU7CisJCQltYy54ZmVyYWRkciA9ICh1MzIpcHRocnVfZG1hX2huZGw7CisKKwkJCS8qCisJCQkgKiBJc3N1ZSB0aGUgY29tbWFuZAorCQkJICovCisJCQltZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgcHRocnUpOworCisJCQlydmFsID0gbWVnYV9uX3RvX20oKHZvaWQgX191c2VyICopYXJnLCAmbWMpOworCisJCQlpZiggcnZhbCApIGdvdG8gZnJlZW1lbV9hbmRfcmV0dXJuOworCisKKwkJCS8qCisJCQkgKiBJcyBkYXRhIGdvaW5nIHVwLXN0cmVhbQorCQkJICovCisJCQlpZiggcHRocnUtPmRhdGF4ZmVybGVuICYmICh1aW9jLmZsYWdzICYgVUlPQ19SRCkgKSB7CisJCQkJaWYoIGNvcHlfdG9fdXNlcigoY2hhciBfX3VzZXIgKil1eGZlcmFkZHIsIGRhdGEsCisJCQkJCQkJcHRocnUtPmRhdGF4ZmVybGVuKSApIHsKKwkJCQkJcnZhbCA9ICgtRUZBVUxUKTsKKwkJCQl9CisJCQl9CisKKwkJCS8qCisJCQkgKiBTZW5kIHRoZSByZXF1ZXN0IHNlbnNlIGRhdGEgYWxzbywgaXJyZXNwZWN0aXZlIG9mCisJCQkgKiB3aGV0aGVyIHRoZSB1c2VyIGhhcyBhc2tlZCBmb3IgaXQgb3Igbm90LgorCQkJICovCisJCQljb3B5X3RvX3VzZXIodXB0aHJ1LT5yZXFzZW5zZWFyZWEsCisJCQkJCXB0aHJ1LT5yZXFzZW5zZWFyZWEsIDE0KTsKKworZnJlZW1lbV9hbmRfcmV0dXJuOgorCQkJaWYoIHB0aHJ1LT5kYXRheGZlcmxlbiApIHsKKwkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCisJCQkJCQlwdGhydS0+ZGF0YXhmZXJsZW4sIGRhdGEsCisJCQkJCQlkYXRhX2RtYV9obmRsKTsKKwkJCX0KKworCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksCisJCQkJCXB0aHJ1LCBwdGhydV9kbWFfaG5kbCk7CisKKwkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKKworCQkJcmV0dXJuIHJ2YWw7CisJCX0KKwkJZWxzZSB7CisJCQkvKiBEQ01EIGNvbW1hbmRzICovCisKKwkJCS8qCisJCQkgKiBJcyB0aGVyZSBhIGRhdGEgdHJhbnNmZXIKKwkJCSAqLworCQkJaWYoIHVpb2MueGZlcmxlbiApIHsKKwkJCQlkYXRhID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwKKwkJCQkJCXVpb2MueGZlcmxlbiwgJmRhdGFfZG1hX2huZGwpOworCisJCQkJaWYoIGRhdGEgPT0gTlVMTCApIHsKKwkJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCQkJCQlyZXR1cm4gKC1FTk9NRU0pOworCQkJCX0KKworCQkJCXV4ZmVyYWRkciA9IE1CT1godWlvYyktPnhmZXJhZGRyOworCQkJfQorCisJCQkvKgorCQkJICogSXMgZGF0YSBjb21pbmcgZG93bi1zdHJlYW0KKwkJCSAqLworCQkJaWYoIHVpb2MueGZlcmxlbiAmJiAodWlvYy5mbGFncyAmIFVJT0NfV1IpICkgeworCQkJCS8qCisJCQkJICogR2V0IHRoZSB1c2VyIGRhdGEKKwkJCQkgKi8KKwkJCQlpZiggY29weV9mcm9tX3VzZXIoZGF0YSwgKGNoYXIgX191c2VyICopdXhmZXJhZGRyLAorCQkJCQkJCXVpb2MueGZlcmxlbikgKSB7CisKKwkJCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LAorCQkJCQkJCXVpb2MueGZlcmxlbiwKKwkJCQkJCQlkYXRhLCBkYXRhX2RtYV9obmRsKTsKKworCQkJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CisKKwkJCQkJcmV0dXJuICgtRUZBVUxUKTsKKwkJCQl9CisJCQl9CisKKwkJCW1lbWNweSgmbWMsIE1CT1godWlvYyksIHNpemVvZihtZWdhY21kX3QpKTsKKworCQkJbWMueGZlcmFkZHIgPSAodTMyKWRhdGFfZG1hX2huZGw7CisKKwkJCS8qCisJCQkgKiBJc3N1ZSB0aGUgY29tbWFuZAorCQkJICovCisJCQltZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCk7CisKKwkJCXJ2YWwgPSBtZWdhX25fdG9fbSgodm9pZCBfX3VzZXIgKilhcmcsICZtYyk7CisKKwkJCWlmKCBydmFsICkgeworCQkJCWlmKCB1aW9jLnhmZXJsZW4gKSB7CisJCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKKwkJCQkJCQl1aW9jLnhmZXJsZW4sIGRhdGEsCisJCQkJCQkJZGF0YV9kbWFfaG5kbCk7CisJCQkJfQorCisJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJCQkJcmV0dXJuIHJ2YWw7CisJCQl9CisKKwkJCS8qCisJCQkgKiBJcyBkYXRhIGdvaW5nIHVwLXN0cmVhbQorCQkJICovCisJCQlpZiggdWlvYy54ZmVybGVuICYmICh1aW9jLmZsYWdzICYgVUlPQ19SRCkgKSB7CisJCQkJaWYoIGNvcHlfdG9fdXNlcigoY2hhciBfX3VzZXIgKil1eGZlcmFkZHIsIGRhdGEsCisJCQkJCQkJdWlvYy54ZmVybGVuKSApIHsKKworCQkJCQlydmFsID0gKC1FRkFVTFQpOworCQkJCX0KKwkJCX0KKworCQkJaWYoIHVpb2MueGZlcmxlbiApIHsKKwkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCisJCQkJCQl1aW9jLnhmZXJsZW4sIGRhdGEsCisJCQkJCQlkYXRhX2RtYV9obmRsKTsKKwkJCX0KKworCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOworCisJCQlyZXR1cm4gcnZhbDsKKwkJfQorCisJZGVmYXVsdDoKKwkJcmV0dXJuICgtRUlOVkFMKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworLyoqCisgKiBtZWdhX21fdG9fbigpCisgKiBAYXJnIC0gdXNlciBhZGRyZXNzCisgKiBAdWlvYyAtIG5ldyBpb2N0bCBzdHJ1Y3R1cmUKKyAqCisgKiBBIHRoaW4gbGF5ZXIgdG8gY29udmVydCBvbGRlciBtaW1kIGludGVyZmFjZSBpb2N0bCBzdHJ1Y3R1cmUgdG8gTklUIGlvY3RsCisgKiBzdHJ1Y3R1cmUKKyAqCisgKiBDb252ZXJ0cyB0aGUgb2xkZXIgbWltZCBpb2N0bCBzdHJ1Y3R1cmUgdG8gbmV3ZXIgTklUIHN0cnVjdHVyZQorICovCitzdGF0aWMgaW50CittZWdhX21fdG9fbih2b2lkIF9fdXNlciAqYXJnLCBuaXRpb2N0bF90ICp1aW9jKQoreworCXN0cnVjdCB1aW9jdGxfdAl1aW9jX21pbWQ7CisJY2hhcglzaWduYXR1cmVbOF0gPSB7MH07CisJdTgJb3Bjb2RlOworCXU4CXN1Ym9wY29kZTsKKworCisJLyoKKwkgKiBjaGVjayBpcyB0aGUgYXBwbGljYXRpb24gY29uZm9ybXMgdG8gTklULiBXZSBkbyBub3QgaGF2ZSB0byBkbyBtdWNoCisJICogaW4gdGhhdCBjYXNlLgorCSAqIFdlIGV4cGxvaXQgdGhlIGZhY3QgdGhhdCB0aGUgc2lnbmF0dXJlIGlzIHN0b3JlZCBpbiB0aGUgdmVyeQorCSAqIGJlZ2luaW5nIG9mIHRoZSBzdHJ1Y3R1cmUuCisJICovCisKKwlpZiggY29weV9mcm9tX3VzZXIoc2lnbmF0dXJlLCBhcmcsIDcpICkKKwkJcmV0dXJuICgtRUZBVUxUKTsKKworCWlmKCBtZW1jbXAoc2lnbmF0dXJlLCAiTUVHQU5JVCIsIDcpID09IDAgKSB7CisKKwkJLyoKKwkJICogTk9URSBOT1RFOiBUaGUgbml0IGlvY3RsIGlzIHN0aWxsIHVuZGVyIGZsdXggYmVjYXVzZSBvZgorCQkgKiBjaGFuZ2Ugb2YgbWFpbGJveCBkZWZpbml0aW9uLCBpbiBIUEUuIE5vIGFwcGxpY2F0aW9ucyB5ZXQKKwkJICogdXNlIHRoaXMgaW50ZXJmYWNlIGFuZCBsZXQncyBub3QgaGF2ZSBhcHBsaWNhdGlvbnMgdXNlIHRoaXMKKwkJICogaW50ZXJmYWNlIHRpbGwgdGhlIG5ldyBzcGVjaWZpdGlvbnMgYXJlIGluIHBsYWNlLgorCQkgKi8KKwkJcmV0dXJuIC1FSU5WQUw7CisjaWYgMAorCQlpZiggY29weV9mcm9tX3VzZXIodWlvYywgYXJnLCBzaXplb2Yobml0aW9jdGxfdCkpICkKKwkJCXJldHVybiAoLUVGQVVMVCk7CisJCXJldHVybiAwOworI2VuZGlmCisJfQorCisJLyoKKwkgKiBFbHNlIGFzc3VtZSB3ZSBoYXZlIG1pbWQgdWlvY3RsX3QgYXMgYXJnLiBDb252ZXJ0IHRvIG5pdGlvY3RsX3QKKwkgKgorCSAqIEdldCB0aGUgdXNlciBpb2N0bCBzdHJ1Y3R1cmUKKwkgKi8KKwlpZiggY29weV9mcm9tX3VzZXIoJnVpb2NfbWltZCwgYXJnLCBzaXplb2Yoc3RydWN0IHVpb2N0bF90KSkgKQorCQlyZXR1cm4gKC1FRkFVTFQpOworCisKKwkvKgorCSAqIEdldCB0aGUgb3Bjb2RlIGFuZCBzdWJvcGNvZGUgZm9yIHRoZSBjb21tYW5kcworCSAqLworCW9wY29kZSA9IHVpb2NfbWltZC51aS5mY3Mub3Bjb2RlOworCXN1Ym9wY29kZSA9IHVpb2NfbWltZC51aS5mY3Muc3Vib3Bjb2RlOworCisJc3dpdGNoIChvcGNvZGUpIHsKKwljYXNlIDB4ODI6CisKKwkJc3dpdGNoIChzdWJvcGNvZGUpIHsKKworCQljYXNlIE1FR0FJT0NfUURSVlJWRVI6CS8qIFF1ZXJ5IGRyaXZlciB2ZXJzaW9uICovCisJCQl1aW9jLT5vcGNvZGUgPSBHRVRfRFJJVkVSX1ZFUjsKKwkJCXVpb2MtPnVpb2NfdWFkZHIgPSB1aW9jX21pbWQuZGF0YTsKKwkJCWJyZWFrOworCisJCWNhc2UgTUVHQUlPQ19RTkFEQVA6CS8qIEdldCAjIG9mIGFkYXB0ZXJzICovCisJCQl1aW9jLT5vcGNvZGUgPSBHRVRfTl9BREFQOworCQkJdWlvYy0+dWlvY191YWRkciA9IHVpb2NfbWltZC5kYXRhOworCQkJYnJlYWs7CisKKwkJY2FzZSBNRUdBSU9DX1FBREFQSU5GTzoJLyogR2V0IGFkYXB0ZXIgaW5mb3JtYXRpb24gKi8KKwkJCXVpb2MtPm9wY29kZSA9IEdFVF9BREFQX0lORk87CisJCQl1aW9jLT5hZGFwbm8gPSB1aW9jX21pbWQudWkuZmNzLmFkYXBubzsKKwkJCXVpb2MtPnVpb2NfdWFkZHIgPSB1aW9jX21pbWQuZGF0YTsKKwkJCWJyZWFrOworCisJCWRlZmF1bHQ6CisJCQlyZXR1cm4oLUVJTlZBTCk7CisJCX0KKworCQlicmVhazsKKworCisJY2FzZSAweDgxOgorCisJCXVpb2MtPm9wY29kZSA9IE1CT1hfQ01EOworCQl1aW9jLT5hZGFwbm8gPSB1aW9jX21pbWQudWkuZmNzLmFkYXBubzsKKworCQltZW1jcHkodWlvYy0+dWlvY19ybWJveCwgdWlvY19taW1kLm1ib3gsIDE4KTsKKworCQl1aW9jLT54ZmVybGVuID0gdWlvY19taW1kLnVpLmZjcy5sZW5ndGg7CisKKwkJaWYoIHVpb2NfbWltZC5vdXRsZW4gKSB1aW9jLT5mbGFncyA9IFVJT0NfUkQ7CisJCWlmKCB1aW9jX21pbWQuaW5sZW4gKSB1aW9jLT5mbGFncyB8PSBVSU9DX1dSOworCisJCWJyZWFrOworCisJY2FzZSAweDgwOgorCisJCXVpb2MtPm9wY29kZSA9IE1CT1hfQ01EOworCQl1aW9jLT5hZGFwbm8gPSB1aW9jX21pbWQudWkuZmNzLmFkYXBubzsKKworCQltZW1jcHkodWlvYy0+dWlvY19ybWJveCwgdWlvY19taW1kLm1ib3gsIDE4KTsKKworCQkvKgorCQkgKiBDaG9vc2UgdGhlIHhmZXJsZW4gYmlnZ2VyIG9mIGlucHV0IGFuZCBvdXRwdXQgZGF0YQorCQkgKi8KKwkJdWlvYy0+eGZlcmxlbiA9IHVpb2NfbWltZC5vdXRsZW4gPiB1aW9jX21pbWQuaW5sZW4gPworCQkJdWlvY19taW1kLm91dGxlbiA6IHVpb2NfbWltZC5pbmxlbjsKKworCQlpZiggdWlvY19taW1kLm91dGxlbiApIHVpb2MtPmZsYWdzID0gVUlPQ19SRDsKKwkJaWYoIHVpb2NfbWltZC5pbmxlbiApIHVpb2MtPmZsYWdzIHw9IFVJT0NfV1I7CisKKwkJYnJlYWs7CisKKwlkZWZhdWx0OgorCQlyZXR1cm4gKC1FSU5WQUwpOworCisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qCisgKiBtZWdhX25fdG9fbSgpCisgKiBAYXJnIC0gdXNlciBhZGRyZXNzCisgKiBAbWMgLSBtYWlsYm94IGNvbW1hbmQKKyAqCisgKiBVcGRhdGVzIHRoZSBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIGFwcGxpY2F0aW9uLCBkZXBlbmRpbmcgb24gYXBwbGljYXRpb24KKyAqIGNvbmZvcm1zIHRvIG9sZGVyIG1pbWQgaW9jdGwgaW50ZXJmYWNlIG9yIG5ld2VyIE5JVCBpb2N0bCBpbnRlcmZhY2UKKyAqLworc3RhdGljIGludAorbWVnYV9uX3RvX20odm9pZCBfX3VzZXIgKmFyZywgbWVnYWNtZF90ICptYykKK3sKKwluaXRpb2N0bF90CV9fdXNlciAqdWlvY3A7CisJbWVnYWNtZF90CV9fdXNlciAqdW1jOworCW1lZ2FfcGFzc3RocnUJX191c2VyICp1cHRocnU7CisJc3RydWN0IHVpb2N0bF90CV9fdXNlciAqdWlvY19taW1kOworCWNoYXIJc2lnbmF0dXJlWzhdID0gezB9OworCisJLyoKKwkgKiBjaGVjayBpcyB0aGUgYXBwbGljYXRpb24gY29uZm9ybXMgdG8gTklULgorCSAqLworCWlmKCBjb3B5X2Zyb21fdXNlcihzaWduYXR1cmUsIGFyZywgNykgKQorCQlyZXR1cm4gLUVGQVVMVDsKKworCWlmKCBtZW1jbXAoc2lnbmF0dXJlLCAiTUVHQU5JVCIsIDcpID09IDAgKSB7CisKKwkJdWlvY3AgPSBhcmc7CisKKwkJaWYoIHB1dF91c2VyKG1jLT5zdGF0dXMsICh1OCBfX3VzZXIgKikmTUJPWF9QKHVpb2NwKS0+c3RhdHVzKSApCisJCQlyZXR1cm4gKC1FRkFVTFQpOworCisJCWlmKCBtYy0+Y21kID09IE1FR0FfTUJPWENNRF9QQVNTVEhSVSApIHsKKworCQkJdW1jID0gTUJPWF9QKHVpb2NwKTsKKworCQkJaWYgKGdldF91c2VyKHVwdGhydSwgKG1lZ2FfcGFzc3RocnUgX191c2VyICogX191c2VyICopJnVtYy0+eGZlcmFkZHIpKQorCQkJCXJldHVybiAtRUZBVUxUOworCisJCQlpZiggcHV0X3VzZXIobWMtPnN0YXR1cywgKHU4IF9fdXNlciAqKSZ1cHRocnUtPnNjc2lzdGF0dXMpKQorCQkJCXJldHVybiAoLUVGQVVMVCk7CisJCX0KKwl9CisJZWxzZSB7CisJCXVpb2NfbWltZCA9IGFyZzsKKworCQlpZiggcHV0X3VzZXIobWMtPnN0YXR1cywgKHU4IF9fdXNlciAqKSZ1aW9jX21pbWQtPm1ib3hbMTddKSApCisJCQlyZXR1cm4gKC1FRkFVTFQpOworCisJCWlmKCBtYy0+Y21kID09IE1FR0FfTUJPWENNRF9QQVNTVEhSVSApIHsKKworCQkJdW1jID0gKG1lZ2FjbWRfdCBfX3VzZXIgKil1aW9jX21pbWQtPm1ib3g7CisKKwkJCWlmIChnZXRfdXNlcih1cHRocnUsIChtZWdhX3Bhc3N0aHJ1IF9fdXNlciAqIF9fdXNlciAqKSZ1bWMtPnhmZXJhZGRyKSkKKwkJCQlyZXR1cm4gKC1FRkFVTFQpOworCisJCQlpZiggcHV0X3VzZXIobWMtPnN0YXR1cywgKHU4IF9fdXNlciAqKSZ1cHRocnUtPnNjc2lzdGF0dXMpICkKKwkJCQlyZXR1cm4gKC1FRkFVTFQpOworCQl9CisJfQorCisJcmV0dXJuIDA7Cit9CisKKworLyoKKyAqIE1FR0FSQUlEICdGVycgY29tbWFuZHMuCisgKi8KKworLyoqCisgKiBtZWdhX2lzX2Jpb3NfZW5hYmxlZCgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBpc3N1ZSBjb21tYW5kIHRvIGZpbmQgb3V0IGlmIHRoZSBCSU9TIGlzIGVuYWJsZWQgZm9yIHRoaXMgY29udHJvbGxlcgorICovCitzdGF0aWMgaW50CittZWdhX2lzX2Jpb3NfZW5hYmxlZChhZGFwdGVyX3QgKmFkYXB0ZXIpCit7CisJdW5zaWduZWQgY2hhcglyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CisJbWJveF90CSptYm94OworCWludAlyZXQ7CisKKwltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OworCisJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CisKKwltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CisKKwltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CisKKwlyYXdfbWJveFswXSA9IElTX0JJT1NfRU5BQkxFRDsKKwlyYXdfbWJveFsyXSA9IEdFVF9CSU9TOworCisKKwlyZXQgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOworCisJcmV0dXJuICooY2hhciAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOworfQorCisKKy8qKgorICogbWVnYV9lbnVtX3JhaWRfc2NzaSgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBGaW5kIG91dCB3aGF0IGNoYW5uZWxzIGFyZSBSQUlEL1NDU0kuIFRoaXMgaW5mb3JtYXRpb24gaXMgdXNlZCB0bworICogZGlmZmVyZW50aWF0ZSB0aGUgdmlydHVhbCBjaGFubmVscyBhbmQgcGh5c2ljYWwgY2hhbm5lbHMgYW5kIHRvIHN1cHBvcnQKKyAqIFJPTUIgZmVhdHVyZSBhbmQgbm9uLWRpc2sgZGV2aWNlcy4KKyAqLworc3RhdGljIHZvaWQKK21lZ2FfZW51bV9yYWlkX3Njc2koYWRhcHRlcl90ICphZGFwdGVyKQoreworCXVuc2lnbmVkIGNoYXIgcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOworCW1ib3hfdCAqbWJveDsKKwlpbnQgaTsKKworCW1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CisKKwltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKKworCS8qCisJICogaXNzdWUgY29tbWFuZCB0byBmaW5kIG91dCB3aGF0IGNoYW5uZWxzIGFyZSByYWlkL3Njc2kKKwkgKi8KKwlyYXdfbWJveFswXSA9IENITkxfQ0xBU1M7CisJcmF3X21ib3hbMl0gPSBHRVRfQ0hOTF9DTEFTUzsKKworCW1lbXNldCgodm9pZCAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCAwLCBNRUdBX0JVRkZFUl9TSVpFKTsKKworCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gKHUzMilhZGFwdGVyLT5idWZfZG1hX2hhbmRsZTsKKworCS8qCisJICogTm9uLVJPTUIgZmlybXdhcmUgZmFpbCB0aGlzIGNvbW1hbmQsIHNvIGFsbCBjaGFubmVscworCSAqIG11c3QgYmUgc2hvd24gUkFJRAorCSAqLworCWFkYXB0ZXItPm1lZ2FfY2hfY2xhc3MgPSAweEZGOworCisJaWYoIWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCkpIHsKKwkJYWRhcHRlci0+bWVnYV9jaF9jbGFzcyA9ICooKGNoYXIgKilhZGFwdGVyLT5tZWdhX2J1ZmZlcik7CisKKwl9CisKKwlmb3IoIGkgPSAwOyBpIDwgYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsgaSsrICkgeyAKKwkJaWYoIChhZGFwdGVyLT5tZWdhX2NoX2NsYXNzID4+IGkpICYgMHgwMSApIHsKKwkJCXByaW50ayhLRVJOX0lORk8gIm1lZ2FyYWlkOiBjaGFubmVsWyVkXSBpcyByYWlkLlxuIiwKKwkJCQkJaSk7CisJCX0KKwkJZWxzZSB7CisJCQlwcmludGsoS0VSTl9JTkZPICJtZWdhcmFpZDogY2hhbm5lbFslZF0gaXMgc2NzaS5cbiIsCisJCQkJCWkpOworCQl9CisJfQorCisJcmV0dXJuOworfQorCisKKy8qKgorICogbWVnYV9nZXRfYm9vdF9kcnYoKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRmluZCBvdXQgd2hpY2ggZGV2aWNlIGlzIHRoZSBib290IGRldmljZS4gTm90ZSwgYW55IGxvZ2ljYWwgZHJpdmUgb3IgYW55CisgKiBwaHlpY2FsIGRldmljZSAoZS5nLiwgYSBDRFJPTSkgY2FuIGJlIGRlc2lnbmF0ZWQgYXMgYSBib290IGRldmljZS4KKyAqLworc3RhdGljIHZvaWQKK21lZ2FfZ2V0X2Jvb3RfZHJ2KGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwlzdHJ1Y3QgcHJpdmF0ZV9iaW9zX2RhdGEJKnBydl9iaW9zX2RhdGE7CisJdW5zaWduZWQgY2hhcglyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CisJbWJveF90CSptYm94OworCXUxNglja3N1bSA9IDA7CisJdTgJKmNrc3VtX3A7CisJdTgJYm9vdF9wZHJ2OworCWludAlpOworCisJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKKworCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOworCisJcmF3X21ib3hbMF0gPSBCSU9TX1BWVF9EQVRBOworCXJhd19tYm94WzJdID0gR0VUX0JJT1NfUFZUX0RBVEE7CisKKwltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CisKKwltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CisKKwlhZGFwdGVyLT5ib290X2xkcnZfZW5hYmxlZCA9IDA7CisJYWRhcHRlci0+Ym9vdF9sZHJ2ID0gMDsKKworCWFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkID0gMDsKKwlhZGFwdGVyLT5ib290X3BkcnZfY2ggPSAwOworCWFkYXB0ZXItPmJvb3RfcGRydl90Z3QgPSAwOworCisJaWYoaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KSA9PSAwKSB7CisJCXBydl9iaW9zX2RhdGEgPQorCQkJKHN0cnVjdCBwcml2YXRlX2Jpb3NfZGF0YSAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOworCisJCWNrc3VtID0gMDsKKwkJY2tzdW1fcCA9IChjaGFyICopcHJ2X2Jpb3NfZGF0YTsKKwkJZm9yIChpID0gMDsgaSA8IDE0OyBpKysgKSB7CisJCQlja3N1bSArPSAodTE2KSgqY2tzdW1fcCsrKTsKKwkJfQorCisJCWlmIChwcnZfYmlvc19kYXRhLT5ja3N1bSA9PSAodTE2KSgwLWNrc3VtKSApIHsKKworCQkJLyoKKwkJCSAqIElmIE1TQiBpcyBzZXQsIGEgcGh5c2ljYWwgZHJpdmUgaXMgc2V0IGFzIGJvb3QKKwkJCSAqIGRldmljZQorCQkJICovCisJCQlpZiggcHJ2X2Jpb3NfZGF0YS0+Ym9vdF9kcnYgJiAweDgwICkgeworCQkJCWFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkID0gMTsKKwkJCQlib290X3BkcnYgPSBwcnZfYmlvc19kYXRhLT5ib290X2RydiAmIDB4N0Y7CisJCQkJYWRhcHRlci0+Ym9vdF9wZHJ2X2NoID0gYm9vdF9wZHJ2IC8gMTY7CisJCQkJYWRhcHRlci0+Ym9vdF9wZHJ2X3RndCA9IGJvb3RfcGRydiAlIDE2OworCQkJfQorCQkJZWxzZSB7CisJCQkJYWRhcHRlci0+Ym9vdF9sZHJ2X2VuYWJsZWQgPSAxOworCQkJCWFkYXB0ZXItPmJvb3RfbGRydiA9IHBydl9iaW9zX2RhdGEtPmJvb3RfZHJ2OworCQkJfQorCQl9CisJfQorCit9CisKKy8qKgorICogbWVnYV9zdXBwb3J0X3JhbmRvbV9kZWwoKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRmluZCBvdXQgaWYgdGhpcyBjb250cm9sbGVyIHN1cHBvcnRzIHJhbmRvbSBkZWxldGlvbiBhbmQgYWRkaXRpb24gb2YKKyAqIGxvZ2ljYWwgZHJpdmVzCisgKi8KK3N0YXRpYyBpbnQKK21lZ2Ffc3VwcG9ydF9yYW5kb21fZGVsKGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwl1bnNpZ25lZCBjaGFyIHJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKKwltYm94X3QgKm1ib3g7CisJaW50IHJ2YWw7CisKKwltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OworCisJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CisKKwkvKgorCSAqIGlzc3VlIGNvbW1hbmQKKwkgKi8KKwlyYXdfbWJveFswXSA9IEZDX0RFTF9MT0dEUlY7CisJcmF3X21ib3hbMl0gPSBPUF9TVVBfREVMX0xPR0RSVjsKKworCXJ2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOworCisJcmV0dXJuICFydmFsOworfQorCisKKy8qKgorICogbWVnYV9zdXBwb3J0X2V4dF9jZGIoKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKgorICogRmluZCBvdXQgaWYgdGhpcyBmaXJtd2FyZSBzdXBwb3J0IGNkYmxlbiA+IDEwCisgKi8KK3N0YXRpYyBpbnQKK21lZ2Ffc3VwcG9ydF9leHRfY2RiKGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwl1bnNpZ25lZCBjaGFyIHJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKKwltYm94X3QgKm1ib3g7CisJaW50IHJ2YWw7CisKKwltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OworCisJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CisJLyoKKwkgKiBpc3N1ZSBjb21tYW5kIHRvIGZpbmQgb3V0IGlmIGNvbnRyb2xsZXIgc3VwcG9ydHMgZXh0ZW5kZWQgQ0RCcy4KKwkgKi8KKwlyYXdfbWJveFswXSA9IDB4QTQ7CisJcmF3X21ib3hbMl0gPSAweDE2OworCisJcnZhbCA9IGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CisKKwlyZXR1cm4gIXJ2YWw7Cit9CisKKworLyoqCisgKiBtZWdhX2RlbF9sb2dkcnYoKQorICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCisgKiBAbG9nZHJ2IC0gbG9naWNhbCBkcml2ZSB0byBiZSBkZWxldGVkCisgKgorICogRGVsZXRlIHRoZSBzcGVjaWZpZWQgbG9naWNhbCBkcml2ZS4gSXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSB1c2VyCisgKiBhcHAgdG8gbGV0IHRoZSBPUyBrbm93IGFib3V0IHRoaXMgb3BlcmF0aW9uLgorICovCitzdGF0aWMgaW50CittZWdhX2RlbF9sb2dkcnYoYWRhcHRlcl90ICphZGFwdGVyLCBpbnQgbG9nZHJ2KQoreworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJc2NiX3QgKnNjYjsKKwlpbnQgcnZhbDsKKworCS8qCisJICogU3RvcCBzZW5kaW5nIGNvbW1hbmRzIHRvIHRoZSBjb250cm9sbGVyLCBxdWV1ZSB0aGVtIGludGVybmFsbHkuCisJICogV2hlbiBkZWxldGlvbiBpcyBjb21wbGV0ZSwgSVNSIHdpbGwgZmx1c2ggdGhlIHF1ZXVlLgorCSAqLworCWF0b21pY19zZXQoJmFkYXB0ZXItPnF1aWVzY2VudCwgMSk7CisKKwkvKgorCSAqIFdhaXQgdGlsbCBhbGwgdGhlIGlzc3VlZCBjb21tYW5kcyBhcmUgY29tcGxldGUgYW5kIHRoZXJlIGFyZSBubworCSAqIGNvbW1hbmRzIGluIHRoZSBwZW5kaW5nIHF1ZXVlCisJICovCisJd2hpbGUgKGF0b21pY19yZWFkKCZhZGFwdGVyLT5wZW5kX2NtZHMpID4gMCB8fAorCSAgICAgICAhbGlzdF9lbXB0eSgmYWRhcHRlci0+cGVuZGluZ19saXN0KSkKKwkJbXNsZWVwKDEwMDApOwkvKiBzbGVlcCBmb3IgMXMgKi8KKworCXJ2YWwgPSBtZWdhX2RvX2RlbF9sb2dkcnYoYWRhcHRlciwgbG9nZHJ2KTsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CisKKwkvKgorCSAqIElmIGRlbGV0ZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwsIGFkZCAweDgwIHRvIHRoZSBsb2dpY2FsIGRyaXZlCisJICogaWRzIGZvciBjb21tYW5kcyBpbiB0aGUgcGVuZGluZyBxdWV1ZS4KKwkgKi8KKwlpZiAoYWRhcHRlci0+cmVhZF9sZGlkbWFwKSB7CisJCXN0cnVjdCBsaXN0X2hlYWQgKnBvczsKKwkJbGlzdF9mb3JfZWFjaChwb3MsICZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpIHsKKwkJCXNjYiA9IGxpc3RfZW50cnkocG9zLCBzY2JfdCwgbGlzdCk7CisJCQlpZiAoc2NiLT5wdGhydS0+bG9nZHJ2IDwgMHg4MCApCisJCQkJc2NiLT5wdGhydS0+bG9nZHJ2ICs9IDB4ODA7CisJCX0KKwl9CisKKwlhdG9taWNfc2V0KCZhZGFwdGVyLT5xdWllc2NlbnQsIDApOworCisJbWVnYV9ydW5wZW5kcShhZGFwdGVyKTsKKworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmFkYXB0ZXItPmxvY2ssIGZsYWdzKTsKKworCXJldHVybiBydmFsOworfQorCisKK3N0YXRpYyBpbnQKK21lZ2FfZG9fZGVsX2xvZ2RydihhZGFwdGVyX3QgKmFkYXB0ZXIsIGludCBsb2dkcnYpCit7CisJbWVnYWNtZF90CW1jOworCWludAlydmFsOworCisJbWVtc2V0KCAmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKKworCW1jLmNtZCA9IEZDX0RFTF9MT0dEUlY7CisJbWMub3Bjb2RlID0gT1BfREVMX0xPR0RSVjsKKwltYy5zdWJvcGNvZGUgPSBsb2dkcnY7CisKKwlydmFsID0gbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpOworCisJLyogbG9nIHRoaXMgZXZlbnQgKi8KKwlpZihydmFsKSB7CisJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBEZWxldGUgTEQtJWQgZmFpbGVkLiIsIGxvZ2Rydik7CisJCXJldHVybiBydmFsOworCX0KKworCS8qCisJICogQWZ0ZXIgZGVsZXRpbmcgZmlyc3QgbG9naWNhbCBkcml2ZSwgdGhlIGxvZ2ljYWwgZHJpdmVzIG11c3QgYmUKKwkgKiBhZGRyZXNzZWQgYnkgYWRkaW5nIDB4ODAgdG8gdGhlIGxvZ2ljYWwgZHJpdmUgaWQuCisJICovCisJYWRhcHRlci0+cmVhZF9sZGlkbWFwID0gMTsKKworCXJldHVybiBydmFsOworfQorCisKKy8qKgorICogbWVnYV9nZXRfbWF4X3NnbCgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBGaW5kIG91dCB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc2NhdHRlci1nYXRoZXIgZWxlbWVudHMgc3VwcG9ydGVkIGJ5IHRoaXMKKyAqIHZlcnNpb24gb2YgdGhlIGZpcm13YXJlCisgKi8KK3N0YXRpYyB2b2lkCittZWdhX2dldF9tYXhfc2dsKGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwl1bnNpZ25lZCBjaGFyCXJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKKwltYm94X3QJKm1ib3g7CisKKwltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OworCisJbWVtc2V0KG1ib3gsIDAsIHNpemVvZihyYXdfbWJveCkpOworCisJbWVtc2V0KCh2b2lkICopYWRhcHRlci0+bWVnYV9idWZmZXIsIDAsIE1FR0FfQlVGRkVSX1NJWkUpOworCisJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAodTMyKWFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlOworCisJcmF3X21ib3hbMF0gPSBNQUlOX01JU0NfT1BDT0RFOworCXJhd19tYm94WzJdID0gR0VUX01BWF9TR19TVVBQT1JUOworCisKKwlpZiggaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KSApIHsKKwkJLyoKKwkJICogZi93IGRvZXMgbm90IHN1cHBvcnQgdGhpcyBjb21tYW5kLiBDaG9vc2UgdGhlIGRlZmF1bHQgdmFsdWUKKwkJICovCisJCWFkYXB0ZXItPnNnbGVuID0gTUlOX1NHTElTVDsKKwl9CisJZWxzZSB7CisJCWFkYXB0ZXItPnNnbGVuID0gKigoY2hhciAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyKTsKKwkJCisJCS8qCisJCSAqIE1ha2Ugc3VyZSB0aGlzIGlzIG5vdCBtb3JlIHRoYW4gdGhlIHJlc291cmNlcyB3ZSBhcmUKKwkJICogcGxhbm5pbmcgdG8gYWxsb2NhdGUKKwkJICovCisJCWlmICggYWRhcHRlci0+c2dsZW4gPiBNQVhfU0dMSVNUICkKKwkJCWFkYXB0ZXItPnNnbGVuID0gTUFYX1NHTElTVDsKKwl9CisKKwlyZXR1cm47Cit9CisKKworLyoqCisgKiBtZWdhX3N1cHBvcnRfY2x1c3RlcigpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqCisgKiBGaW5kIG91dCBpZiB0aGlzIGZpcm13YXJlIHN1cHBvcnQgY2x1c3RlciBjYWxscy4KKyAqLworc3RhdGljIGludAorbWVnYV9zdXBwb3J0X2NsdXN0ZXIoYWRhcHRlcl90ICphZGFwdGVyKQoreworCXVuc2lnbmVkIGNoYXIJcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOworCW1ib3hfdAkqbWJveDsKKworCW1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CisKKwltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CisKKwltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CisKKwltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CisKKwkvKgorCSAqIFRyeSB0byBnZXQgdGhlIGluaXRpYXRvciBpZC4gVGhpcyBjb21tYW5kIHdpbGwgc3VjY2VlZCBpZmYgdGhlCisJICogY2x1c3RlcmluZyBpcyBhdmFpbGFibGUgb24gdGhpcyBIQkEuCisJICovCisJcmF3X21ib3hbMF0gPSBNRUdBX0dFVF9UQVJHRVRfSUQ7CisKKwlpZiggaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KSA9PSAwICkgeworCisJCS8qCisJCSAqIENsdXN0ZXIgc3VwcG9ydCBhdmFpbGFibGUuIEdldCB0aGUgaW5pdGlhdG9yIHRhcmdldCBpZC4KKwkJICogVGVsbCBvdXIgaWQgdG8gbWlkLWxheWVyIHRvby4KKwkJICovCisJCWFkYXB0ZXItPnRoaXNfaWQgPSAqKHUzMiAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOworCQlhZGFwdGVyLT5ob3N0LT50aGlzX2lkID0gYWRhcHRlci0+dGhpc19pZDsKKworCQlyZXR1cm4gMTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworCisvKioKKyAqIG1lZ2FfYWRhcGlucSgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBkbWFfaGFuZGxlIC0gRE1BIGFkZHJlc3Mgb2YgdGhlIGJ1ZmZlcgorICoKKyAqIElzc3VlIGludGVybmFsIGNvbWFtbmRzIHdoaWxlIGludGVycnVwdHMgYXJlIGF2YWlsYWJsZS4KKyAqIFdlIG9ubHkgaXNzdWUgZGlyZWN0IG1haWxib3ggY29tbWFuZHMgZnJvbSB3aXRoaW4gdGhlIGRyaXZlci4gaW9jdGwoKQorICogaW50ZXJmYWNlIHVzaW5nIHRoZXNlIHJvdXRpbmVzIGNhbiBpc3N1ZSBwYXNzdGhydSBjb21tYW5kcy4KKyAqLworc3RhdGljIGludAorbWVnYV9hZGFwaW5xKGFkYXB0ZXJfdCAqYWRhcHRlciwgZG1hX2FkZHJfdCBkbWFfaGFuZGxlKQoreworCW1lZ2FjbWRfdAltYzsKKworCW1lbXNldCgmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKKworCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKKwkJbWMuY21kID0gRkNfTkVXX0NPTkZJRzsKKwkJbWMub3Bjb2RlID0gTkNfU1VCT1BfRU5RVUlSWTM7CisJCW1jLnN1Ym9wY29kZSA9IEVOUTNfR0VUX1NPTElDSVRFRF9GVUxMOworCX0KKwllbHNlIHsKKwkJbWMuY21kID0gTUVHQV9NQk9YQ01EX0FEUEVYVElOUTsKKwl9CisKKwltYy54ZmVyYWRkciA9ICh1MzIpZG1hX2hhbmRsZTsKKworCWlmICggbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpICE9IDAgKSB7CisJCXJldHVybiAtMTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworCisvKiogbWVnYV9pbnRlcm5hbF9kZXZfaW5xdWlyeSgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBjaCAtIGNoYW5uZWwgZm9yIHRoaXMgZGV2aWNlCisgKiBAdGd0IC0gSUQgb2YgdGhpcyBkZXZpY2UKKyAqIEBidWZfZG1hX2hhbmRsZSAtIERNQSBhZGRyZXNzIG9mIHRoZSBidWZmZXIKKyAqCisgKiBJc3N1ZSB0aGUgc2NzaSBpbnF1aXJ5IGZvciB0aGUgc3BlY2lmaWVkIGRldmljZS4KKyAqLworc3RhdGljIGludAorbWVnYV9pbnRlcm5hbF9kZXZfaW5xdWlyeShhZGFwdGVyX3QgKmFkYXB0ZXIsIHU4IGNoLCB1OCB0Z3QsCisJCWRtYV9hZGRyX3QgYnVmX2RtYV9oYW5kbGUpCit7CisJbWVnYV9wYXNzdGhydQkqcHRocnU7CisJZG1hX2FkZHJfdAlwdGhydV9kbWFfaGFuZGxlOworCW1lZ2FjbWRfdAltYzsKKwlpbnQJCXJ2YWw7CisJc3RydWN0IHBjaV9kZXYJKnBkZXY7CisKKworCS8qCisJICogRm9yIGFsbCBpbnRlcm5hbCBjb21tYW5kcywgdGhlIGJ1ZmZlciBtdXN0IGJlIGFsbG9jYXRlZCBpbiA8NEdCCisJICogYWRkcmVzcyByYW5nZQorCSAqLworCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSByZXR1cm4gLTE7CisKKwlwdGhydSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsIHNpemVvZihtZWdhX3Bhc3N0aHJ1KSwKKwkJCSZwdGhydV9kbWFfaGFuZGxlKTsKKworCWlmKCBwdGhydSA9PSBOVUxMICkgeworCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CisJCXJldHVybiAtMTsKKwl9CisKKwlwdGhydS0+dGltZW91dCA9IDI7CisJcHRocnUtPmFycyA9IDE7CisJcHRocnUtPnJlcXNlbnNlbGVuID0gMTQ7CisJcHRocnUtPmlzbG9naWNhbCA9IDA7CisKKwlwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2g7CisKKwlwdGhydS0+dGFyZ2V0ID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/IChjaCA8PCA0KXx0Z3QgOiB0Z3Q7CisKKwlwdGhydS0+Y2RibGVuID0gNjsKKworCXB0aHJ1LT5jZGJbMF0gPSBJTlFVSVJZOworCXB0aHJ1LT5jZGJbMV0gPSAwOworCXB0aHJ1LT5jZGJbMl0gPSAwOworCXB0aHJ1LT5jZGJbM10gPSAwOworCXB0aHJ1LT5jZGJbNF0gPSAyNTU7CisJcHRocnUtPmNkYls1XSA9IDA7CisKKworCXB0aHJ1LT5kYXRheGZlcmFkZHIgPSAodTMyKWJ1Zl9kbWFfaGFuZGxlOworCXB0aHJ1LT5kYXRheGZlcmxlbiA9IDI1NjsKKworCW1lbXNldCgmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKKworCW1jLmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKKwltYy54ZmVyYWRkciA9ICh1MzIpcHRocnVfZG1hX2hhbmRsZTsKKworCXJ2YWwgPSBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgcHRocnUpOworCisJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksIHB0aHJ1LAorCQkJcHRocnVfZG1hX2hhbmRsZSk7CisKKwlmcmVlX2xvY2FsX3BkZXYocGRldik7CisKKwlyZXR1cm4gcnZhbDsKK30KKworCisvKioKKyAqIG1lZ2FfaW50ZXJuYWxfY29tbWFuZCgpCisgKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKKyAqIEBscyAtIHRoZSBzY29wZSBvZiB0aGUgZXhjbHVzaW9uIGxvY2suCisgKiBAbWMgLSB0aGUgbWFpbGJveCBjb21tYW5kCisgKiBAcHRocnUgLSBQYXNzdGhydSBzdHJ1Y3R1cmUgZm9yIERDREIgY29tbWFuZHMKKyAqCisgKiBJc3N1ZSB0aGUgaW50ZXJuYWwgY29tbWFuZHMgaW4gaW50ZXJydXB0IG1vZGUuCisgKiBUaGUgbGFzdCBhcmd1bWVudCBpcyB0aGUgYWRkcmVzcyBvZiB0aGUgcGFzc3RocnUgc3RydWN0dXJlIGlmIHRoZSBjb21tYW5kCisgKiB0byBiZSBmaXJlZCBpcyBhIHBhc3N0aHJ1IGNvbW1hbmQKKyAqCisgKiBsb2Nrc2NvcGUgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIGNhbGxlciBoYXMgYWxyZWFkeSBhY3F1aXJlZCB0aGUgbG9jay4gT2YKKyAqIGNvdXJzZSwgdGhlIGNhbGxlciBtdXN0IGtub3cgd2hpY2ggbG9jayB3ZSBhcmUgdGFsa2luZyBhYm91dC4KKyAqCisgKiBOb3RlOiBwYXJhbWV0ZXIgJ3B0aHJ1JyBpcyBudWxsIGZvciBub24tcGFzc3RocnUgY29tbWFuZHMuCisgKi8KK3N0YXRpYyBpbnQKK21lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyX3QgKmFkYXB0ZXIsIGxvY2tzY29wZV90IGxzLCBtZWdhY21kX3QgKm1jLAorCQltZWdhX3Bhc3N0aHJ1ICpwdGhydSApCit7CisJU2NzaV9DbW5kCSpzY21kOworCXN0cnVjdAlzY3NpX2RldmljZSAqc2RldjsKKwl1bnNpZ25lZCBsb25nCWZsYWdzID0gMDsKKwlzY2JfdAkqc2NiOworCWludAlydmFsOworCisJLyoKKwkgKiBUaGUgaW50ZXJuYWwgY29tbWFuZHMgc2hhcmUgb25lIGNvbW1hbmQgaWQgYW5kIGhlbmNlIGFyZQorCSAqIHNlcmlhbGl6ZWQuIFRoaXMgaXMgc28gYmVjYXVzZSB3ZSB3YW50IHRvIHJlc2VydmUgbWF4aW11bSBudW1iZXIgb2YKKwkgKiBhdmFpbGFibGUgY29tbWFuZCBpZHMgZm9yIHRoZSBJL08gY29tbWFuZHMuCisJICovCisJZG93bigmYWRhcHRlci0+aW50X210eCk7CisKKwlzY2IgPSAmYWRhcHRlci0+aW50X3NjYjsKKwltZW1zZXQoc2NiLCAwLCBzaXplb2Yoc2NiX3QpKTsKKworCXNjbWQgPSAmYWRhcHRlci0+aW50X3NjbWQ7CisJbWVtc2V0KHNjbWQsIDAsIHNpemVvZihTY3NpX0NtbmQpKTsKKworCXNkZXYgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3Qgc2NzaV9kZXZpY2UpLCBHRlBfS0VSTkVMKTsKKwltZW1zZXQoc2RldiwgMCwgc2l6ZW9mKHN0cnVjdCBzY3NpX2RldmljZSkpOworCXNjbWQtPmRldmljZSA9IHNkZXY7CisKKwlzY21kLT5kZXZpY2UtPmhvc3QgPSBhZGFwdGVyLT5ob3N0OworCXNjbWQtPmJ1ZmZlciA9ICh2b2lkICopc2NiOworCXNjbWQtPmNtbmRbMF0gPSBNRUdBX0lOVEVSTkFMX0NNRDsKKworCXNjYi0+c3RhdGUgfD0gU0NCX0FDVElWRTsKKwlzY2ItPmNtZCA9IHNjbWQ7CisKKwltZW1jcHkoc2NiLT5yYXdfbWJveCwgbWMsIHNpemVvZihtZWdhY21kX3QpKTsKKworCS8qCisJICogSXMgaXQgYSBwYXNzdGhydSBjb21tYW5kCisJICovCisJaWYoIG1jLT5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVICkgeworCisJCXNjYi0+cHRocnUgPSBwdGhydTsKKwl9CisKKwlzY2ItPmlkeCA9IENNRElEX0lOVF9DTURTOworCisJc2NtZC0+c3RhdGUgPSAwOworCisJLyoKKwkgKiBHZXQgdGhlIGxvY2sgb25seSBpZiB0aGUgY2FsbGVyIGhhcyBub3QgYWNxdWlyZWQgaXQgYWxyZWFkeQorCSAqLworCWlmKCBscyA9PSBMT0NLX0lOVCApIHNwaW5fbG9ja19pcnFzYXZlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CisKKwltZWdhcmFpZF9xdWV1ZShzY21kLCBtZWdhX2ludGVybmFsX2RvbmUpOworCisJaWYoIGxzID09IExPQ0tfSU5UICkgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOworCisJLyoKKwkgKiBXYWl0IHRpbGwgdGhpcyBjb21tYW5kIGZpbmlzaGVzLiBEbyBub3QgdXNlCisJICogd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlKCkuIEl0IGNhdXNlcyBwYW5pYyBpZiBDVFJMLUMgaXMgaGl0IHdoZW4KKwkgKiBkdW1waW5nIGUuZy4sIHBoeXNpY2FsIGRpc2sgaW5mb3JtYXRpb24gdGhyb3VnaCAvcHJvYyBpbnRlcmZhY2UuCisJICovCisjaWYgMAorCXdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZShhZGFwdGVyLT5pbnRfd2FpdHEsIHNjbWQtPnN0YXRlKTsKKyNlbmRpZgorCXdhaXRfZXZlbnQoYWRhcHRlci0+aW50X3dhaXRxLCBzY21kLT5zdGF0ZSk7CisKKwlydmFsID0gc2NtZC0+cmVzdWx0OworCW1jLT5zdGF0dXMgPSBzY21kLT5yZXN1bHQ7CisJa2ZyZWUoc2Rldik7CisKKwkvKgorCSAqIFByaW50IGEgZGVidWcgbWVzc2FnZSBmb3IgYWxsIGZhaWxlZCBjb21tYW5kcy4gQXBwbGljYXRpb25zIGNhbiB1c2UKKwkgKiB0aGlzIGluZm9ybWF0aW9uLgorCSAqLworCWlmKCBzY21kLT5yZXN1bHQgJiYgdHJhY2VfbGV2ZWwgKSB7CisJCXByaW50aygibWVnYXJhaWQ6IGNtZCBbJXgsICV4LCAleF0gc3RhdHVzOlsleF1cbiIsCisJCQltYy0+Y21kLCBtYy0+b3Bjb2RlLCBtYy0+c3Vib3Bjb2RlLCBzY21kLT5yZXN1bHQpOworCX0KKworCXVwKCZhZGFwdGVyLT5pbnRfbXR4KTsKKworCXJldHVybiBydmFsOworfQorCisKKy8qKgorICogbWVnYV9pbnRlcm5hbF9kb25lKCkKKyAqIEBzY21kIC0gaW50ZXJuYWwgc2NzaSBjb21tYW5kCisgKgorICogQ2FsbGJhY2sgcm91dGluZSBmb3IgaW50ZXJuYWwgY29tbWFuZHMuCisgKi8KK3N0YXRpYyB2b2lkCittZWdhX2ludGVybmFsX2RvbmUoU2NzaV9DbW5kICpzY21kKQoreworCWFkYXB0ZXJfdAkqYWRhcHRlcjsKKworCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopc2NtZC0+ZGV2aWNlLT5ob3N0LT5ob3N0ZGF0YTsKKworCXNjbWQtPnN0YXRlID0gMTsgLyogdGhyZWFkIHdhaXRpbmcgZm9yIGl0cyBjb21tYW5kIHRvIGNvbXBsZXRlICovCisKKwkvKgorCSAqIFNlZSBjb21tZW50IGluIG1lZ2FfaW50ZXJuYWxfY29tbWFuZCgpIHJvdXRpbmUgZm9yCisJICogd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlKCkKKwkgKi8KKyNpZiAwCisJd2FrZV91cF9pbnRlcnJ1cHRpYmxlKCZhZGFwdGVyLT5pbnRfd2FpdHEpOworI2VuZGlmCisJd2FrZV91cCgmYWRhcHRlci0+aW50X3dhaXRxKTsKKworfQorCisKK3N0YXRpYyBzdHJ1Y3Qgc2NzaV9ob3N0X3RlbXBsYXRlIG1lZ2FyYWlkX3RlbXBsYXRlID0geworCS5tb2R1bGUJCQkJPSBUSElTX01PRFVMRSwKKwkubmFtZQkJCQk9ICJNZWdhUkFJRCIsCisJLnByb2NfbmFtZQkJCT0gIm1lZ2FyYWlkIiwKKwkuaW5mbwkJCQk9IG1lZ2FyYWlkX2luZm8sCisJLnF1ZXVlY29tbWFuZAkJCT0gbWVnYXJhaWRfcXVldWUsCQorCS5iaW9zX3BhcmFtCQkJPSBtZWdhcmFpZF9iaW9zcGFyYW0sCisJLm1heF9zZWN0b3JzCQkJPSBNQVhfU0VDVE9SU19QRVJfSU8sCisJLmNhbl9xdWV1ZQkJCT0gTUFYX0NPTU1BTkRTLAorCS50aGlzX2lkCQkJPSBERUZBVUxUX0lOSVRJQVRPUl9JRCwKKwkuc2dfdGFibGVzaXplCQkJPSBNQVhfU0dMSVNULAorCS5jbWRfcGVyX2x1bgkJCT0gREVGX0NNRF9QRVJfTFVOLAorCS51c2VfY2x1c3RlcmluZwkJCT0gRU5BQkxFX0NMVVNURVJJTkcsCisJLmVoX2Fib3J0X2hhbmRsZXIJCT0gbWVnYXJhaWRfYWJvcnQsCisJLmVoX2RldmljZV9yZXNldF9oYW5kbGVyCT0gbWVnYXJhaWRfcmVzZXQsCisJLmVoX2J1c19yZXNldF9oYW5kbGVyCQk9IG1lZ2FyYWlkX3Jlc2V0LAorCS5laF9ob3N0X3Jlc2V0X2hhbmRsZXIJCT0gbWVnYXJhaWRfcmVzZXQsCit9OworCitzdGF0aWMgaW50IF9fZGV2aW5pdAorbWVnYXJhaWRfcHJvYmVfb25lKHN0cnVjdCBwY2lfZGV2ICpwZGV2LCBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQpCit7CisJc3RydWN0IFNjc2lfSG9zdCAqaG9zdDsKKwlhZGFwdGVyX3QgKmFkYXB0ZXI7CisJdW5zaWduZWQgbG9uZyBtZWdhX2Jhc2Vwb3J0LCB0YmFzZSwgZmxhZyA9IDA7CisJdTE2IHN1YnN5c2lkLCBzdWJzeXN2aWQ7CisJdTggcGNpX2J1cywgcGNpX2Rldl9mdW5jOworCWludCBpcnEsIGksIGo7CisJaW50IGVycm9yID0gLUVOT0RFVjsKKworCWlmIChwY2lfZW5hYmxlX2RldmljZShwZGV2KSkKKwkJZ290byBvdXQ7CisJcGNpX3NldF9tYXN0ZXIocGRldik7CisKKwlwY2lfYnVzID0gcGRldi0+YnVzLT5udW1iZXI7CisJcGNpX2Rldl9mdW5jID0gcGRldi0+ZGV2Zm47CisKKwkvKgorCSAqIFRoZSBtZWdhcmFpZDMgc3R1ZmYgcmVwb3J0cyB0aGUgSUQgb2YgdGhlIEludGVsIHBhcnQgd2hpY2ggaXMgbm90CisJICogcmVtb3RlbHkgc3BlY2lmaWMgdG8gdGhlIG1lZ2FyYWlkCisJICovCisJaWYgKHBkZXYtPnZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0lOVEVMKSB7CisJCXUxNiBtYWdpYzsKKwkJLyoKKwkJICogRG9uJ3QgZmFsbCBvdmVyIHRoZSBDb21wYXEgbWFuYWdlbWVudCBjYXJkcyB1c2luZyB0aGUgc2FtZQorCQkgKiBQQ0kgaWRlbnRpZmllcgorCQkgKi8KKwkJaWYgKHBkZXYtPnN1YnN5c3RlbV92ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9DT01QQVEgJiYKKwkJICAgIHBkZXYtPnN1YnN5c3RlbV9kZXZpY2UgPT0gMHhDMDAwKQorCQkgICAJcmV0dXJuIC1FTk9ERVY7CisJCS8qIE5vdyBjaGVjayB0aGUgbWFnaWMgc2lnbmF0dXJlIGJ5dGUgKi8KKwkJcGNpX3JlYWRfY29uZmlnX3dvcmQocGRldiwgUENJX0NPTkZfQU1JU0lHLCAmbWFnaWMpOworCQlpZiAobWFnaWMgIT0gSEJBX1NJR05BVFVSRV80NzEgJiYgbWFnaWMgIT0gSEJBX1NJR05BVFVSRSkKKwkJCXJldHVybiAtRU5PREVWOworCQkvKiBPayBpdCBpcyBwcm9iYWJseSBhIG1lZ2FyYWlkICovCisJfQorCisJLyoKKwkgKiBGb3IgdGhlc2UgdmVuZG9yIGFuZCBkZXZpY2UgaWRzLCBzaWduYXR1cmUgb2Zmc2V0cyBhcmUgbm90CisJICogdmFsaWQgYW5kIDY0IGJpdCBpcyBpbXBsaWNpdAorCSAqLworCWlmIChpZC0+ZHJpdmVyX2RhdGEgJiBCT0FSRF82NEJJVCkKKwkJZmxhZyB8PSBCT0FSRF82NEJJVDsKKwllbHNlIHsKKwkJdTMyIG1hZ2ljNjQ7CisKKwkJcGNpX3JlYWRfY29uZmlnX2R3b3JkKHBkZXYsIFBDSV9DT05GX0FNSVNJRzY0LCAmbWFnaWM2NCk7CisJCWlmIChtYWdpYzY0ID09IEhCQV9TSUdOQVRVUkVfNjRCSVQpCisJCQlmbGFnIHw9IEJPQVJEXzY0QklUOworCX0KKworCXN1YnN5c3ZpZCA9IHBkZXYtPnN1YnN5c3RlbV92ZW5kb3I7CisJc3Vic3lzaWQgPSBwZGV2LT5zdWJzeXN0ZW1fZGV2aWNlOworCisJcHJpbnRrKEtFUk5fTk9USUNFICJtZWdhcmFpZDogZm91bmQgMHglNC4wNHg6MHglNC4wNHg6YnVzICVkOiIsCisJCWlkLT52ZW5kb3IsIGlkLT5kZXZpY2UsIHBjaV9idXMpOworCisJcHJpbnRrKCJzbG90ICVkOmZ1bmMgJWRcbiIsCisJCVBDSV9TTE9UKHBjaV9kZXZfZnVuYyksIFBDSV9GVU5DKHBjaV9kZXZfZnVuYykpOworCisJLyogUmVhZCB0aGUgYmFzZSBwb3J0IGFuZCBJUlEgZnJvbSBQQ0kgKi8KKwltZWdhX2Jhc2Vwb3J0ID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDApOworCWlycSA9IHBkZXYtPmlycTsKKworCXRiYXNlID0gbWVnYV9iYXNlcG9ydDsKKwlpZiAocGNpX3Jlc291cmNlX2ZsYWdzKHBkZXYsIDApICYgSU9SRVNPVVJDRV9NRU0pIHsKKwkJZmxhZyB8PSBCT0FSRF9NRU1NQVA7CisKKwkJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24obWVnYV9iYXNlcG9ydCwgMTI4LCAibWVnYXJhaWQiKSkgeworCQkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IG1lbSByZWdpb24gYnVzeSFcbiIpOworCQkJZ290byBvdXRfZGlzYWJsZV9kZXZpY2U7CisJCX0KKworCQltZWdhX2Jhc2Vwb3J0ID0gKHVuc2lnbmVkIGxvbmcpaW9yZW1hcChtZWdhX2Jhc2Vwb3J0LCAxMjgpOworCQlpZiAoIW1lZ2FfYmFzZXBvcnQpIHsKKwkJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCSAgICAgICAibWVnYXJhaWQ6IGNvdWxkIG5vdCBtYXAgaGJhIG1lbW9yeVxuIik7CisJCQlnb3RvIG91dF9yZWxlYXNlX3JlZ2lvbjsKKwkJfQorCX0gZWxzZSB7CisJCWZsYWcgfD0gQk9BUkRfSU9NQVA7CisJCW1lZ2FfYmFzZXBvcnQgKz0gMHgxMDsKKworCQlpZiAoIXJlcXVlc3RfcmVnaW9uKG1lZ2FfYmFzZXBvcnQsIDE2LCAibWVnYXJhaWQiKSkKKwkJCWdvdG8gb3V0X2Rpc2FibGVfZGV2aWNlOworCX0KKworCS8qIEluaXRpYWxpemUgU0NTSSBIb3N0IHN0cnVjdHVyZSAqLworCWhvc3QgPSBzY3NpX2hvc3RfYWxsb2MoJm1lZ2FyYWlkX3RlbXBsYXRlLCBzaXplb2YoYWRhcHRlcl90KSk7CisJaWYgKCFob3N0KQorCQlnb3RvIG91dF9pb3VubWFwOworCisJYWRhcHRlciA9IChhZGFwdGVyX3QgKilob3N0LT5ob3N0ZGF0YTsKKwltZW1zZXQoYWRhcHRlciwgMCwgc2l6ZW9mKGFkYXB0ZXJfdCkpOworCisJcHJpbnRrKEtFUk5fTk9USUNFCisJCSJzY3NpJWQ6Rm91bmQgTWVnYVJBSUQgY29udHJvbGxlciBhdCAweCVseCwgSVJROiVkXG4iLAorCQlob3N0LT5ob3N0X25vLCBtZWdhX2Jhc2Vwb3J0LCBpcnEpOworCisJYWRhcHRlci0+YmFzZSA9IG1lZ2FfYmFzZXBvcnQ7CisKKwlJTklUX0xJU1RfSEVBRCgmYWRhcHRlci0+ZnJlZV9saXN0KTsKKwlJTklUX0xJU1RfSEVBRCgmYWRhcHRlci0+cGVuZGluZ19saXN0KTsKKwlJTklUX0xJU1RfSEVBRCgmYWRhcHRlci0+Y29tcGxldGVkX2xpc3QpOworCisJYWRhcHRlci0+ZmxhZyA9IGZsYWc7CisJc3Bpbl9sb2NrX2luaXQoJmFkYXB0ZXItPmxvY2spOworCXNjc2lfYXNzaWduX2xvY2soaG9zdCwgJmFkYXB0ZXItPmxvY2spOworCisJaG9zdC0+Y21kX3Blcl9sdW4gPSBtYXhfY21kX3Blcl9sdW47CisJaG9zdC0+bWF4X3NlY3RvcnMgPSBtYXhfc2VjdG9yc19wZXJfaW87CisKKwlhZGFwdGVyLT5kZXYgPSBwZGV2OworCWFkYXB0ZXItPmhvc3QgPSBob3N0OworCisJYWRhcHRlci0+aG9zdC0+aXJxID0gaXJxOworCisJaWYgKGZsYWcgJiBCT0FSRF9NRU1NQVApCisJCWFkYXB0ZXItPmhvc3QtPmJhc2UgPSB0YmFzZTsKKwllbHNlIHsKKwkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCA9IHRiYXNlOworCQlhZGFwdGVyLT5ob3N0LT5uX2lvX3BvcnQgPSAxNjsKKwl9CisKKwlhZGFwdGVyLT5ob3N0LT51bmlxdWVfaWQgPSAocGNpX2J1cyA8PCA4KSB8IHBjaV9kZXZfZnVuYzsKKworCS8qCisJICogQWxsb2NhdGUgYnVmZmVyIHRvIGlzc3VlIGludGVybmFsIGNvbW1hbmRzLgorCSAqLworCWFkYXB0ZXItPm1lZ2FfYnVmZmVyID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LAorCQlNRUdBX0JVRkZFUl9TSVpFLCAmYWRhcHRlci0+YnVmX2RtYV9oYW5kbGUpOworCWlmICghYWRhcHRlci0+bWVnYV9idWZmZXIpIHsKKwkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IG91dCBvZiBSQU0uXG4iKTsKKwkJZ290byBvdXRfaG9zdF9wdXQ7CisJfQorCisJYWRhcHRlci0+c2NiX2xpc3QgPSBrbWFsbG9jKHNpemVvZihzY2JfdCkgKiBNQVhfQ09NTUFORFMsIEdGUF9LRVJORUwpOworCWlmICghYWRhcHRlci0+c2NiX2xpc3QpIHsKKwkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IG91dCBvZiBSQU0uXG4iKTsKKwkJZ290byBvdXRfZnJlZV9jbWRfYnVmZmVyOworCX0KKworCWlmIChyZXF1ZXN0X2lycShpcnEsIChhZGFwdGVyLT5mbGFnICYgQk9BUkRfTUVNTUFQKSA/CisJCQkJbWVnYXJhaWRfaXNyX21lbW1hcHBlZCA6IG1lZ2FyYWlkX2lzcl9pb21hcHBlZCwKKwkJCQkJU0FfU0hJUlEsICJtZWdhcmFpZCIsIGFkYXB0ZXIpKSB7CisJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCSJtZWdhcmFpZDogQ291bGRuJ3QgcmVnaXN0ZXIgSVJRICVkIVxuIiwgaXJxKTsKKwkJZ290byBvdXRfZnJlZV9zY2JfbGlzdDsKKwl9CisKKwlpZiAobWVnYV9zZXR1cF9tYWlsYm94KGFkYXB0ZXIpKQorCQlnb3RvIG91dF9mcmVlX2lycTsKKworCWlmIChtZWdhX3F1ZXJ5X2FkYXB0ZXIoYWRhcHRlcikpCisJCWdvdG8gb3V0X2ZyZWVfbWJveDsKKworCS8qCisJICogSGF2ZSBjaGVja3MgZm9yIHNvbWUgYnVnZ3kgZi93CisJICovCisJaWYgKChzdWJzeXNpZCA9PSAweDExMTEpICYmIChzdWJzeXN2aWQgPT0gMHgxMTExKSkgeworCQkvKgorCQkgKiBXaGljaCBmaXJtd2FyZQorCQkgKi8KKwkJaWYgKCFzdHJjbXAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIjMuMDAiKSB8fAorCQkJCSFzdHJjbXAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIjMuMDEiKSkgeworCisJCQlwcmludGsoIEtFUk5fV0FSTklORworCQkJCSJtZWdhcmFpZDogWW91ciAgY2FyZCBpcyBhIERlbGwgUEVSQyAiCisJCQkJIjIvU0MgUkFJRCBjb250cm9sbGVyIHdpdGggICIKKwkJCQkiZmlybXdhcmVcbm1lZ2FyYWlkOiAzLjAwIG9yIDMuMDEuICAiCisJCQkJIlRoaXMgZHJpdmVyIGlzIGtub3duIHRvIGhhdmUgIgorCQkJCSJjb3JydXB0aW9uIGlzc3Vlc1xubWVnYXJhaWQ6IHdpdGggIgorCQkJCSJ0aG9zZSBmaXJtd2FyZSB2ZXJzaW9ucyBvbiB0aGlzICIKKwkJCQkic3BlY2lmaWMgY2FyZC4gIEluIG9yZGVyXG5tZWdhcmFpZDogIgorCQkJCSJ0byBwcm90ZWN0IHlvdXIgZGF0YSwgcGxlYXNlIHVwZ3JhZGUgIgorCQkJCSJ5b3VyIGZpcm13YXJlIHRvIHZlcnNpb25cbm1lZ2FyYWlkOiAiCisJCQkJIjMuMTAgb3IgbGF0ZXIsIGF2YWlsYWJsZSBmcm9tIHRoZSAiCisJCQkJIkRlbGwgVGVjaG5pY2FsIFN1cHBvcnQgd2ViXG4iCisJCQkJIm1lZ2FyYWlkOiBzaXRlIGF0XG5odHRwOi8vc3VwcG9ydC4iCisJCQkJImRlbGwuY29tL3VzL2VuL2ZpbGVsaWIvZG93bmxvYWQvIgorCQkJCSJpbmRleC5hc3A/ZmlsZWlkPTI5NDBcbiIKKwkJCSk7CisJCX0KKwl9CisKKwkvKgorCSAqIElmIHdlIGhhdmUgYSBIUCAxTSgweDYwRTcpLzJNKDB4NjBFOCkgY29udHJvbGxlciB3aXRoCisJICogZmlybXdhcmUgSC4wMS4wNywgSC4wMS4wOCwgYW5kIEguMDEuMDkgZGlzYWJsZSA2NCBiaXQKKwkgKiBzdXBwb3J0LCBzaW5jZSB0aGlzIGZpcm13YXJlIGNhbm5vdCBoYW5kbGUgNjQgYml0CisJICogYWRkcmVzc2luZworCSAqLworCWlmICgoc3Vic3lzdmlkID09IEhQX1NVQlNZU19WSUQpICYmCisJICAgICgoc3Vic3lzaWQgPT0gMHg2MEU3KSB8fCAoc3Vic3lzaWQgPT0gMHg2MEU4KSkpIHsKKwkJLyoKKwkJICogd2hpY2ggZmlybXdhcmUKKwkJICovCisJCWlmICghc3RyY21wKGFkYXB0ZXItPmZ3X3ZlcnNpb24sICJIMDEuMDciKSB8fAorCQkgICAgIXN0cmNtcChhZGFwdGVyLT5md192ZXJzaW9uLCAiSDAxLjA4IikgfHwKKwkJICAgICFzdHJjbXAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIkgwMS4wOSIpICkgeworCQkJcHJpbnRrKEtFUk5fV0FSTklORworCQkJCSJtZWdhcmFpZDogRmlybXdhcmUgSC4wMS4wNywgIgorCQkJCSJILjAxLjA4LCBhbmQgSC4wMS4wOSBvbiAxTS8yTSAiCisJCQkJImNvbnRyb2xsZXJzXG4iCisJCQkJIm1lZ2FyYWlkOiBkbyBub3Qgc3VwcG9ydCA2NCBiaXQgIgorCQkJCSJhZGRyZXNzaW5nLlxubWVnYXJhaWQ6IERJU0FCTElORyAiCisJCQkJIjY0IGJpdCBzdXBwb3J0LlxuIik7CisJCQlhZGFwdGVyLT5mbGFnICY9IH5CT0FSRF82NEJJVDsKKwkJfQorCX0KKworCWlmIChtZWdhX2lzX2Jpb3NfZW5hYmxlZChhZGFwdGVyKSkKKwkJbWVnYV9oYmFzW2hiYV9jb3VudF0uaXNfYmlvc19lbmFibGVkID0gMTsKKwltZWdhX2hiYXNbaGJhX2NvdW50XS5ob3N0ZGF0YV9hZGRyID0gYWRhcHRlcjsKKworCS8qCisJICogRmluZCBvdXQgd2hpY2ggY2hhbm5lbCBpcyByYWlkIGFuZCB3aGljaCBpcyBzY3NpLiBUaGlzIGlzCisJICogZm9yIFJPTUIgc3VwcG9ydC4KKwkgKi8KKwltZWdhX2VudW1fcmFpZF9zY3NpKGFkYXB0ZXIpOworCisJLyoKKwkgKiBGaW5kIG91dCBpZiBhIGxvZ2ljYWwgZHJpdmUgaXMgc2V0IGFzIHRoZSBib290IGRyaXZlLiBJZgorCSAqIHRoZXJlIGlzIG9uZSwgd2lsbCBtYWtlIHRoYXQgYXMgdGhlIGZpcnN0IGxvZ2ljYWwgZHJpdmUuCisJICogUk9NQjogRG8gd2UgaGF2ZSB0byBib290IGZyb20gYSBwaHlzaWNhbCBkcml2ZS4gVGhlbiBhbGwKKwkgKiB0aGUgcGh5c2ljYWwgZHJpdmVzIHdvdWxkIGFwcGVhciBiZWZvcmUgdGhlIGxvZ2ljYWwgZGlza3MuCisJICogRWxzZSwgYWxsIHRoZSBwaHlzaWNhbCBkcml2ZXMgd291bGQgYmUgZXhwb3J0ZWQgdG8gdGhlIG1pZAorCSAqIGxheWVyIGFmdGVyIGxvZ2ljYWwgZHJpdmVzLgorCSAqLworCW1lZ2FfZ2V0X2Jvb3RfZHJ2KGFkYXB0ZXIpOworCisJaWYgKGFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkKSB7CisJCWogPSBhZGFwdGVyLT5wcm9kdWN0X2luZm8ubmNoYW5uZWxzOworCQlmb3IoIGkgPSAwOyBpIDwgajsgaSsrICkKKwkJCWFkYXB0ZXItPmxvZ2Rydl9jaGFuW2ldID0gMDsKKwkJZm9yKCBpID0gajsgaSA8IE5WSVJUX0NIQU4gKyBqOyBpKysgKQorCQkJYWRhcHRlci0+bG9nZHJ2X2NoYW5baV0gPSAxOworCX0gZWxzZSB7CisJCWZvciAoaSA9IDA7IGkgPCBOVklSVF9DSEFOOyBpKyspCisJCQlhZGFwdGVyLT5sb2dkcnZfY2hhbltpXSA9IDE7CisJCWZvciAoaSA9IE5WSVJUX0NIQU47IGkgPCBNQVhfQ0hBTk5FTFMrTlZJUlRfQ0hBTjsgaSsrKQorCQkJYWRhcHRlci0+bG9nZHJ2X2NoYW5baV0gPSAwOworCQlhZGFwdGVyLT5tZWdhX2NoX2NsYXNzIDw8PSBOVklSVF9DSEFOOworCX0KKworCS8qCisJICogRG8gd2Ugc3VwcG9ydCByYW5kb20gZGVsZXRpb24gYW5kIGFkZGl0aW9uIG9mIGxvZ2ljYWwKKwkgKiBkcml2ZXMKKwkgKi8KKwlhZGFwdGVyLT5yZWFkX2xkaWRtYXAgPSAwOwkvKiBzZXQgaXQgYWZ0ZXIgZmlyc3QgbG9nZHJ2CisJCQkJCQkgICBkZWxldGUgY21kICovCisJYWRhcHRlci0+c3VwcG9ydF9yYW5kb21fZGVsID0gbWVnYV9zdXBwb3J0X3JhbmRvbV9kZWwoYWRhcHRlcik7CisKKwkvKiBJbml0aWFsaXplIFNDQnMgKi8KKwlpZiAobWVnYV9pbml0X3NjYihhZGFwdGVyKSkKKwkJZ290byBvdXRfZnJlZV9tYm94OworCisJLyoKKwkgKiBSZXNldCB0aGUgcGVuZGluZyBjb21tYW5kcyBjb3VudGVyCisJICovCisJYXRvbWljX3NldCgmYWRhcHRlci0+cGVuZF9jbWRzLCAwKTsKKworCS8qCisJICogUmVzZXQgdGhlIGFkYXB0ZXIgcXVpZXNjZW50IGZsYWcKKwkgKi8KKwlhdG9taWNfc2V0KCZhZGFwdGVyLT5xdWllc2NlbnQsIDApOworCisJaGJhX3NvZnRfc3RhdGVbaGJhX2NvdW50XSA9IGFkYXB0ZXI7CisKKwkvKgorCSAqIEZpbGwgaW4gdGhlIHN0cnVjdHVyZSB3aGljaCBuZWVkcyB0byBiZSBwYXNzZWQgYmFjayB0byB0aGUKKwkgKiBhcHBsaWNhdGlvbiB3aGVuIGl0IGRvZXMgYW4gaW9jdGwoKSBmb3IgY29udHJvbGxlciByZWxhdGVkCisJICogaW5mb3JtYXRpb24uCisJICovCisJaSA9IGhiYV9jb3VudDsKKworCW1jb250cm9sbGVyW2ldLmJhc2UgPSBtZWdhX2Jhc2Vwb3J0OworCW1jb250cm9sbGVyW2ldLmlycSA9IGlycTsKKwltY29udHJvbGxlcltpXS5udW1sZHJ2ID0gYWRhcHRlci0+bnVtbGRydjsKKwltY29udHJvbGxlcltpXS5wY2lidXMgPSBwY2lfYnVzOworCW1jb250cm9sbGVyW2ldLnBjaWRldiA9IGlkLT5kZXZpY2U7CisJbWNvbnRyb2xsZXJbaV0ucGNpZnVuID0gUENJX0ZVTkMgKHBjaV9kZXZfZnVuYyk7CisJbWNvbnRyb2xsZXJbaV0ucGNpaWQgPSAtMTsKKwltY29udHJvbGxlcltpXS5wY2l2ZW5kb3IgPSBpZC0+dmVuZG9yOworCW1jb250cm9sbGVyW2ldLnBjaXNsb3QgPSBQQ0lfU0xPVChwY2lfZGV2X2Z1bmMpOworCW1jb250cm9sbGVyW2ldLnVpZCA9IChwY2lfYnVzIDw8IDgpIHwgcGNpX2Rldl9mdW5jOworCisKKwkvKiBTZXQgdGhlIE1vZGUgb2YgYWRkcmVzc2luZyB0byA2NCBiaXQgaWYgd2UgY2FuICovCisJaWYgKChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNjRCSVQpICYmIChzaXplb2YoZG1hX2FkZHJfdCkgPT0gOCkpIHsKKwkJcGNpX3NldF9kbWFfbWFzayhwZGV2LCAweGZmZmZmZmZmZmZmZmZmZmZVTEwpOworCQlhZGFwdGVyLT5oYXNfNjRiaXRfYWRkciA9IDE7CisJfSBlbHNlICB7CisJCXBjaV9zZXRfZG1hX21hc2socGRldiwgMHhmZmZmZmZmZik7CisJCWFkYXB0ZXItPmhhc182NGJpdF9hZGRyID0gMDsKKwl9CisJCQorCWluaXRfTVVURVgoJmFkYXB0ZXItPmludF9tdHgpOworCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmFkYXB0ZXItPmludF93YWl0cSk7CisKKwlhZGFwdGVyLT50aGlzX2lkID0gREVGQVVMVF9JTklUSUFUT1JfSUQ7CisJYWRhcHRlci0+aG9zdC0+dGhpc19pZCA9IERFRkFVTFRfSU5JVElBVE9SX0lEOworCisjaWYgTUVHQV9IQVZFX0NMVVNURVJJTkcKKwkvKgorCSAqIElzIGNsdXN0ZXIgc3VwcG9ydCBlbmFibGVkIG9uIHRoaXMgY29udHJvbGxlcgorCSAqIE5vdGU6IEluIGEgY2x1c3RlciB0aGUgSEJBcyAoIHRoZSBpbml0aWF0b3JzICkgd2lsbCBoYXZlCisJICogZGlmZmVyZW50IHRhcmdldCBJRHMgYW5kIHdlIGNhbm5vdCBhc3N1bWUgaXQgdG8gYmUgNy4gQ2FsbAorCSAqIHRvIG1lZ2Ffc3VwcG9ydF9jbHVzdGVyKCkgd2lsbCBnZXQgdGhlIHRhcmdldCBpZHMgYWxzbyBpZgorCSAqIHRoZSBjbHVzdGVyIHN1cHBvcnQgaXMgYXZhaWxhYmxlCisJICovCisJYWRhcHRlci0+aGFzX2NsdXN0ZXIgPSBtZWdhX3N1cHBvcnRfY2x1c3RlcihhZGFwdGVyKTsKKwlpZiAoYWRhcHRlci0+aGFzX2NsdXN0ZXIpIHsKKwkJcHJpbnRrKEtFUk5fTk9USUNFCisJCQkibWVnYXJhaWQ6IENsdXN0ZXIgZHJpdmVyLCBpbml0aWF0b3IgaWQ6JWRcbiIsCisJCQlhZGFwdGVyLT50aGlzX2lkKTsKKwl9CisjZW5kaWYKKworCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBob3N0KTsKKworCW1lZ2FfY3JlYXRlX3Byb2NfZW50cnkoaGJhX2NvdW50LCBtZWdhX3Byb2NfZGlyX2VudHJ5KTsKKworCWVycm9yID0gc2NzaV9hZGRfaG9zdChob3N0LCAmcGRldi0+ZGV2KTsKKwlpZiAoZXJyb3IpCisJCWdvdG8gb3V0X2ZyZWVfbWJveDsKKworCXNjc2lfc2Nhbl9ob3N0KGhvc3QpOworCWhiYV9jb3VudCsrOworCXJldHVybiAwOworCisgb3V0X2ZyZWVfbWJveDoKKwlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgc2l6ZW9mKG1ib3g2NF90KSwKKwkJCWFkYXB0ZXItPnVuYV9tYm94NjQsIGFkYXB0ZXItPnVuYV9tYm94NjRfZG1hKTsKKyBvdXRfZnJlZV9pcnE6CisJZnJlZV9pcnEoYWRhcHRlci0+aG9zdC0+aXJxLCBhZGFwdGVyKTsKKyBvdXRfZnJlZV9zY2JfbGlzdDoKKwlrZnJlZShhZGFwdGVyLT5zY2JfbGlzdCk7Cisgb3V0X2ZyZWVfY21kX2J1ZmZlcjoKKwlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgTUVHQV9CVUZGRVJfU0laRSwKKwkJCWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCBhZGFwdGVyLT5idWZfZG1hX2hhbmRsZSk7Cisgb3V0X2hvc3RfcHV0OgorCXNjc2lfaG9zdF9wdXQoaG9zdCk7Cisgb3V0X2lvdW5tYXA6CisJaWYgKGZsYWcgJiBCT0FSRF9NRU1NQVApCisJCWlvdW5tYXAoKHZvaWQgKiltZWdhX2Jhc2Vwb3J0KTsKKyBvdXRfcmVsZWFzZV9yZWdpb246CisJaWYgKGZsYWcgJiBCT0FSRF9NRU1NQVApCisJCXJlbGVhc2VfbWVtX3JlZ2lvbih0YmFzZSwgMTI4KTsKKwllbHNlCisJCXJlbGVhc2VfcmVnaW9uKG1lZ2FfYmFzZXBvcnQsIDE2KTsKKyBvdXRfZGlzYWJsZV9kZXZpY2U6CisJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOworIG91dDoKKwlyZXR1cm4gZXJyb3I7Cit9CisKK3N0YXRpYyB2b2lkCitfX21lZ2FyYWlkX3NodXRkb3duKGFkYXB0ZXJfdCAqYWRhcHRlcikKK3sKKwl1X2NoYXIJcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOworCW1ib3hfdAkqbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKKwlpbnQJaTsKKworCS8qIEZsdXNoIGFkYXB0ZXIgY2FjaGUgKi8KKwltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKKwlyYXdfbWJveFswXSA9IEZMVVNIX0FEQVBURVI7CisKKwlmcmVlX2lycShhZGFwdGVyLT5ob3N0LT5pcnEsIGFkYXB0ZXIpOworCisJLyogSXNzdWUgYSBibG9ja2luZyAoaW50ZXJydXB0cyBkaXNhYmxlZCkgY29tbWFuZCB0byB0aGUgY2FyZCAqLworCWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CisKKwkvKiBGbHVzaCBkaXNrcyBjYWNoZSAqLworCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOworCXJhd19tYm94WzBdID0gRkxVU0hfU1lTVEVNOworCisJLyogSXNzdWUgYSBibG9ja2luZyAoaW50ZXJydXB0cyBkaXNhYmxlZCkgY29tbWFuZCB0byB0aGUgY2FyZCAqLworCWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CisJCisJaWYgKGF0b21pY19yZWFkKCZhZGFwdGVyLT5wZW5kX2NtZHMpID4gMCkKKwkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IHBlbmRpbmcgY29tbWFuZHMhIVxuIik7CisKKwkvKgorCSAqIEhhdmUgYSBkZWxpYnJhdGUgZGVsYXkgdG8gbWFrZSBzdXJlIGFsbCB0aGUgY2FjaGVzIGFyZQorCSAqIGFjdHVhbGx5IGZsdXNoZWQuCisJICovCisJZm9yIChpID0gMDsgaSA8PSAxMDsgaSsrKQorCQltZGVsYXkoMTAwMCk7Cit9CisKK3N0YXRpYyB2b2lkCittZWdhcmFpZF9yZW1vdmVfb25lKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQoreworCXN0cnVjdCBTY3NpX0hvc3QgKmhvc3QgPSBwY2lfZ2V0X2RydmRhdGEocGRldik7CisJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOworCWNoYXIJYnVmWzEyXSA9IHsgMCB9OworCisJc2NzaV9yZW1vdmVfaG9zdChob3N0KTsKKworCV9fbWVnYXJhaWRfc2h1dGRvd24oYWRhcHRlcik7CisKKwkvKiBGcmVlIG91ciByZXNvdXJjZXMgKi8KKwlpZiAoYWRhcHRlci0+ZmxhZyAmIEJPQVJEX01FTU1BUCkgeworCQlpb3VubWFwKCh2b2lkICopYWRhcHRlci0+YmFzZSk7CisJCXJlbGVhc2VfbWVtX3JlZ2lvbihhZGFwdGVyLT5ob3N0LT5iYXNlLCAxMjgpOworCX0gZWxzZQorCQlyZWxlYXNlX3JlZ2lvbihhZGFwdGVyLT5iYXNlLCAxNik7CisKKwltZWdhX2ZyZWVfc2dsKGFkYXB0ZXIpOworCisjaWZkZWYgQ09ORklHX1BST0NfRlMKKwlpZiAoYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSkgeworCQlyZW1vdmVfcHJvY19lbnRyeSgic3RhdCIsIGFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworCQlyZW1vdmVfcHJvY19lbnRyeSgiY29uZmlnIiwKKwkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKKwkJcmVtb3ZlX3Byb2NfZW50cnkoIm1haWxib3giLAorCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworI2lmIE1FR0FfSEFWRV9FTkhfUFJPQworCQlyZW1vdmVfcHJvY19lbnRyeSgicmVidWlsZC1yYXRlIiwKKwkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKKwkJcmVtb3ZlX3Byb2NfZW50cnkoImJhdHRlcnktc3RhdHVzIiwKKwkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKKworCQlyZW1vdmVfcHJvY19lbnRyeSgiZGlza2RyaXZlcy1jaDAiLAorCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworCQlyZW1vdmVfcHJvY19lbnRyeSgiZGlza2RyaXZlcy1jaDEiLAorCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworCQlyZW1vdmVfcHJvY19lbnRyeSgiZGlza2RyaXZlcy1jaDIiLAorCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworCQlyZW1vdmVfcHJvY19lbnRyeSgiZGlza2RyaXZlcy1jaDMiLAorCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworCisJCXJlbW92ZV9wcm9jX2VudHJ5KCJyYWlkZHJpdmVzLTAtOSIsCisJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CisJCXJlbW92ZV9wcm9jX2VudHJ5KCJyYWlkZHJpdmVzLTEwLTE5IiwKKwkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKKwkJcmVtb3ZlX3Byb2NfZW50cnkoInJhaWRkcml2ZXMtMjAtMjkiLAorCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOworCQlyZW1vdmVfcHJvY19lbnRyeSgicmFpZGRyaXZlcy0zMC0zOSIsCisJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CisjZW5kaWYKKwkJc3ByaW50ZihidWYsICJoYmElZCIsIGFkYXB0ZXItPmhvc3QtPmhvc3Rfbm8pOworCQlyZW1vdmVfcHJvY19lbnRyeShidWYsIG1lZ2FfcHJvY19kaXJfZW50cnkpOworCX0KKyNlbmRpZgorCisJcGNpX2ZyZWVfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsIE1FR0FfQlVGRkVSX1NJWkUsCisJCQlhZGFwdGVyLT5tZWdhX2J1ZmZlciwgYWRhcHRlci0+YnVmX2RtYV9oYW5kbGUpOworCWtmcmVlKGFkYXB0ZXItPnNjYl9saXN0KTsKKwlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgc2l6ZW9mKG1ib3g2NF90KSwKKwkJCWFkYXB0ZXItPnVuYV9tYm94NjQsIGFkYXB0ZXItPnVuYV9tYm94NjRfZG1hKTsKKworCXNjc2lfaG9zdF9wdXQoaG9zdCk7CisJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOworCisJaGJhX2NvdW50LS07Cit9CisKK3N0YXRpYyB2b2lkCittZWdhcmFpZF9zaHV0ZG93bihzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3RydWN0IFNjc2lfSG9zdCAqaG9zdCA9IHBjaV9nZXRfZHJ2ZGF0YSh0b19wY2lfZGV2KGRldikpOworCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilob3N0LT5ob3N0ZGF0YTsKKworCV9fbWVnYXJhaWRfc2h1dGRvd24oYWRhcHRlcik7Cit9CisKK3N0YXRpYyBzdHJ1Y3QgcGNpX2RldmljZV9pZCBtZWdhcmFpZF9wY2lfdGJsW10gPSB7CisJe1BDSV9WRU5ET1JfSURfREVMTCwgUENJX0RFVklDRV9JRF9ESVNDT1ZFUlksCisJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAorCXtQQ0lfVkVORE9SX0lEX0RFTEwsIFBDSV9ERVZJQ0VfSURfUEVSQzRfREksCisJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIEJPQVJEXzY0QklUfSwKKwl7UENJX1ZFTkRPUl9JRF9MU0lfTE9HSUMsIFBDSV9ERVZJQ0VfSURfUEVSQzRfUUNfVkVSREUsCisJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIEJPQVJEXzY0QklUfSwKKwl7UENJX1ZFTkRPUl9JRF9BTUksIFBDSV9ERVZJQ0VfSURfQU1JX01FR0FSQUlELAorCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCAwfSwKKwl7UENJX1ZFTkRPUl9JRF9BTUksIFBDSV9ERVZJQ0VfSURfQU1JX01FR0FSQUlEMiwKKwkJUENJX0FOWV9JRCwgUENJX0FOWV9JRCwgMCwgMCwgMH0sCisJe1BDSV9WRU5ET1JfSURfQU1JLCBQQ0lfREVWSUNFX0lEX0FNSV9NRUdBUkFJRDMsCisJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAorCXtQQ0lfVkVORE9SX0lEX0lOVEVMLCBQQ0lfREVWSUNFX0lEX0FNSV9NRUdBUkFJRDMsCisJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAorCXtQQ0lfVkVORE9SX0lEX0xTSV9MT0dJQywgUENJX0RFVklDRV9JRF9BTUlfTUVHQVJBSUQzLAorCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCAwfSwKKwl7MCx9Cit9OworTU9EVUxFX0RFVklDRV9UQUJMRShwY2ksIG1lZ2FyYWlkX3BjaV90YmwpOworCitzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgbWVnYXJhaWRfcGNpX2RyaXZlciA9IHsKKwkubmFtZQkJPSAibWVnYXJhaWQiLAorCS5pZF90YWJsZQk9IG1lZ2FyYWlkX3BjaV90YmwsCisJLnByb2JlCQk9IG1lZ2FyYWlkX3Byb2JlX29uZSwKKwkucmVtb3ZlCQk9IF9fZGV2ZXhpdF9wKG1lZ2FyYWlkX3JlbW92ZV9vbmUpLAorCS5kcml2ZXIJCT0geworCQkuc2h1dGRvd24gPSBtZWdhcmFpZF9zaHV0ZG93biwKKwl9LAorfTsKKworc3RhdGljIGludCBfX2luaXQgbWVnYXJhaWRfaW5pdCh2b2lkKQoreworCWludCBlcnJvcjsKKworCWlmICgobWF4X2NtZF9wZXJfbHVuIDw9IDApIHx8IChtYXhfY21kX3Blcl9sdW4gPiBNQVhfQ01EX1BFUl9MVU4pKQorCQltYXhfY21kX3Blcl9sdW4gPSBNQVhfQ01EX1BFUl9MVU47CisJaWYgKG1heF9tYm94X2J1c3lfd2FpdCA+IE1CT1hfQlVTWV9XQUlUKQorCQltYXhfbWJveF9idXN5X3dhaXQgPSBNQk9YX0JVU1lfV0FJVDsKKworI2lmZGVmIENPTkZJR19QUk9DX0ZTCisJbWVnYV9wcm9jX2Rpcl9lbnRyeSA9IHByb2NfbWtkaXIoIm1lZ2FyYWlkIiwgJnByb2Nfcm9vdCk7CisJaWYgKCFtZWdhX3Byb2NfZGlyX2VudHJ5KSB7CisJCXByaW50ayhLRVJOX1dBUk5JTkcKKwkJCQkibWVnYXJhaWQ6IGZhaWxlZCB0byBjcmVhdGUgbWVnYXJhaWQgcm9vdFxuIik7CisJfQorI2VuZGlmCisJZXJyb3IgPSBwY2lfbW9kdWxlX2luaXQoJm1lZ2FyYWlkX3BjaV9kcml2ZXIpOworCWlmIChlcnJvcikgeworI2lmZGVmIENPTkZJR19QUk9DX0ZTCisJCXJlbW92ZV9wcm9jX2VudHJ5KCJtZWdhcmFpZCIsICZwcm9jX3Jvb3QpOworI2VuZGlmCisJCXJldHVybiBlcnJvcjsKKwl9CisKKwkvKgorCSAqIFJlZ2lzdGVyIHRoZSBkcml2ZXIgYXMgYSBjaGFyYWN0ZXIgZGV2aWNlLCBmb3IgYXBwbGljYXRpb25zCisJICogdG8gYWNjZXNzIGl0IGZvciBpb2N0bHMuCisJICogRmlyc3QgYXJndW1lbnQgKG1ham9yKSB0byByZWdpc3Rlcl9jaHJkZXYgaW1wbGllcyBhIGR5bmFtaWMKKwkgKiBtYWpvciBudW1iZXIgYWxsb2NhdGlvbi4KKwkgKi8KKwltYWpvciA9IHJlZ2lzdGVyX2NocmRldigwLCAibWVnYWRldiIsICZtZWdhZGV2X2ZvcHMpOworCWlmICghbWFqb3IpIHsKKwkJcHJpbnRrKEtFUk5fV0FSTklORworCQkJCSJtZWdhcmFpZDogZmFpbGVkIHRvIHJlZ2lzdGVyIGNoYXIgZGV2aWNlXG4iKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgX19leGl0IG1lZ2FyYWlkX2V4aXQodm9pZCkKK3sKKwkvKgorCSAqIFVucmVnaXN0ZXIgdGhlIGNoYXJhY3RlciBkZXZpY2UgaW50ZXJmYWNlIHRvIHRoZSBkcml2ZXIuCisJICovCisJdW5yZWdpc3Rlcl9jaHJkZXYobWFqb3IsICJtZWdhZGV2Iik7CisKKwlwY2lfdW5yZWdpc3Rlcl9kcml2ZXIoJm1lZ2FyYWlkX3BjaV9kcml2ZXIpOworCisjaWZkZWYgQ09ORklHX1BST0NfRlMKKwlyZW1vdmVfcHJvY19lbnRyeSgibWVnYXJhaWQiLCAmcHJvY19yb290KTsKKyNlbmRpZgorfQorCittb2R1bGVfaW5pdChtZWdhcmFpZF9pbml0KTsKK21vZHVsZV9leGl0KG1lZ2FyYWlkX2V4aXQpOworCisvKiB2aTogc2V0IHRzPTggc3c9OCB0dz03ODogKi8K